У меня возникла ситуация, когда я вызываю веб-службу, и она возвращает мне HTML-код в 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>
Мне нужно получить ссылки ссылка на предыдущую записьи ссылка на следующую запись... чтобы я мог получить больше данных по этим ссылкам.
Я использую XmlPullParserдля разбора предоставленного выше XML/HTML. Чтобы получить ссылки на следующий/предыдущий элементы, я делаю следующее:
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;
}
}
Выдает XmlPullParserExceptionпри выполнении parser.nextText()... и значение текстовый элемент в это время << Prev.. я думаю, что это значение неправильно понимается с начальным тегом из-за присутствия <<в тексте ..
Подробности LogCat:
04-08 18:32:09.827: W/System.err(688): org.xmlpull.v1.XmlPullParserException: precondition: START_TAG (position:END_TAG </text>@9:2535 in java.io.InputStreamReader@44c6d0d8)
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)
Надеюсь, я объяснил свою проблему.
Вдохновленный подходом Мартинак преобразованию полученных данных сначала в строку, я решил свою проблему с помощью своего рода смешанного подхода.
Преобразование полученного значения InputStreamв строку и замена ошибочных символов на * (или что угодно): следующим образом
InputStreamReader isr = new InputStreamReader(serviceReturnedStream);
BufferedReader br = новый BufferedReader(isr);
StringBuilder xmlAsString = новый StringBuilder (512);
Струнная линия;
пытаться {
в то время как ((строка = br.readLine()) != ноль) {
xmlAsString.append(line.replace("<<", "*").replace(">>", "*"));
}
} поймать (IOException e) {
e.printStackTrace();
}
Теперь у меня есть строка, содержащая правильные XML-данные (для моего случая), так что просто используйте обычный XmlPullParser для ее разбора, а не вручную:
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware (ложь);
Анализатор XmlPullParser = factory.newPullParser();
parser.setInput(новый StringReader(xmlAsString.toString()));
Надеюсь, это кому-нибудь поможет!