Tôi có một tình huống mà tôi gọi một dịch vụ web và nó trả về cho tôi một số HTML trong một phong bì XML. như:Android org.xmlpull.v1.XmlPullParserException khi phân tích cú pháp XML
<xml version="1.0" cache="false">
<head/>
<body>
<table>
<tr>
<td>
<a href="link-to-prev-post">
<text color="red"><< Prev</text>
</a>
</td>
<td>
<a href="link-to-next-post">
<text color="red">| Next >></text>
</a>
</td>
</tr>
</table>
</body>
</xml>
tôi phải lấy dữ liệu link-to-prev-bài & link-to-next-bài liên kết .. vì vậy tôi có thể nhận được nhiều hơn thông qua những liên kết này.
Tôi đang sử dụng XmlPullParser để phân tích cú pháp XML/HTML được cung cấp ở trên. Để có được các liên kết cho các hạng mục/trước hôm sau, tôi đang làm như sau:
if (xmlNodeName.equalsIgnoreCase("a")) {
link = parser.getAttributeValue(null, "href");
} else if (xmlNodeName.equalsIgnoreCase("text")) {
color = parser.getAttributeValue(null, "color");
if (color.equalsIgnoreCase("red") && parser.getEventType() == XmlPullParser.START_TAG) {
// check for next/prev blog entries links
// but this parser.nextText() throws XmlPullParserException
// i think because the nextText() returns << Prev which the parser considers to be wrong
String innerText = parser.nextText();
if (innerText.contains("<< Prev")) {
blog.setPrevBlogItemsUrl(link);
} else if (innerText.contains("Next >>")) {
blog.setNextBlogItemsUrl(link);
}
}
link = null;
}
}
Nó ném XmlPullParserException về thi hành parser.nextText() ... và giá trị của các yếu tố văn bản tại đây thời gian là < < Trước .. tôi nghĩ rằng nó hiểu sai giá trị này với thẻ bắt đầu bởi vì sự hiện diện của < < trong văn bản ..
chi tiết LogCat là:
04-08 18:32:09.827: W/System.err(688): org.xmlpull.v1.XmlPullParserException: precondition: START_TAG (position:END_TAG </text>@9:2535 in [email protected])
04-08 18:32:09.827: W/System.err(688): at org.kxml2.io.KXmlParser.exception(KXmlParser.java:245)
04-08 18:32:09.827: W/System.err(688): at org.kxml2.io.KXmlParser.nextText(KXmlParser.java:1382)
04-08 18:32:09.827: W/System.err(688): at utilities.XMLParserHelper.parseBlogEntries(XMLParserHelper.java:139)
04-08 18:32:09.827: W/System.err(688): at serviceclients.PlayerSummaryAsyncTask.doInBackground(PlayerSummaryAsyncTask.java:68)
04-08 18:32:09.827: W/System.err(688): at serviceclients.PlayerSummaryAsyncTask.doInBackground(PlayerSummaryAsyncTask.java:1)
04-08 18:32:09.836: W/System.err(688): at android.os.AsyncTask$2.call(AsyncTask.java:185)
04-08 18:32:09.836: W/System.err(688): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
04-08 18:32:09.836: W/System.err(688): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
04-08 18:32:09.836: W/System.err(688): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
04-08 18:32:09.836: W/System.err(688): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
04-08 18:32:09.836: W/System.err(688): at java.lang.Thread.run(Thread.java:1096)
Tôi hy vọng tôi đã làm rõ vấn đề của mình.
Giải pháp
Isnpired bởi Martin's phương pháp chuyển đổi các dữ liệu nhận được đầu tiên chuỗi, tôi quản lý vấn đề của tôi trong một loại phương pháp hỗn hợp.
Chuyển đổi giá trị nhận InputStream 's để chuỗi và thay thế các ký tự sai lầm với * (hoặc bất cứ điều gì bạn muốn): như sau
InputStreamReader isr = new InputStreamReader(serviceReturnedStream); BufferedReader br = new BufferedReader(isr); StringBuilder xmlAsString = new StringBuilder(512); String line; try { while ((line = br.readLine()) != null) { xmlAsString.append(line.replace("<<", "*").replace(">>", "*")); } } catch (IOException e) { e.printStackTrace(); }
Bây giờ tôi có một chuỗi chứa đúng Dữ liệu XML (cho trường hợp của tôi), do đó, chỉ cần sử dụng XmlPullParser bình thường để phân tích cú pháp thay vì phân tích cú pháp theo cách thủ công:
XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); factory.setNamespaceAware(false); XmlPullParser parser = factory.newPullParser(); parser.setInput(new StringReader(xmlAsString.toString()));
Hy vọng điều này sẽ giúp ai đó!
cảm ơn cho lời giải thích ... thực sự tôi không có quyền kiểm soát dịch vụ web nên tôi không thể thay đổi whats trả về ... bằng cách sử dụng biểu thức chính quy âm thanh tốt nhưng vấn đề phát sinh khi tôi cố gắng đọc dữ liệu bằng cách sử dụng _parser.nextText() _ .. vì vậy tôi nghĩ rằng regex không thể được sử dụng cũng như bcoz tôi sẽ phải đầu tiên nhận được văn bản trước khi phân tích nó thông qua regex .. nhưng nếu u nghĩ rằng nó có thể được thực hiện sau đó u có thể vui lòng cung cấp cho tôi một số s ví dụ phong phú ?? điều đó thật tuyệt. – Aamir
Tôi rất vui được trợ giúp! Tôi đã thực sự đề cập đến việc phân tích cú pháp toàn bộ XML theo cách thủ công, tức là không sử dụng trình phân tích cú pháp XML chút nào (vì nó không phải là XML hợp lệ mà bạn đang phân tích cú pháp). –
ok tôi umnderstand bây giờ .. nhưng làm thế nào u sẽ đề xuất phân tích thủ công như vậy? Tôi đang tìm kiếm một ví dụ .. tôi bị kẹt sai – Aamir