Android org.xmlpull.v1.XmlPullParserException podczas analizowania XML
Mam sytuację, w której wywołuję usługę internetową i zwraca mi HTML w kopercie XML. lubić:
<code><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> </code>
Muszę odzyskaćlink-to-prev-post & link-to-next-post linki .. dzięki czemu mogę uzyskać więcej danych za pośrednictwem tych linków.
ja używamXmlPullParser analizować podany powyżej XML / HTML. Aby uzyskać linki do następnych / poprzednich pozycji, wykonuję następujące czynności:
<code>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; } } </code>
To rzucaXmlPullParserException na wykonanieparser.nextText () ... a wartością elementu tekstowego w tej chwili jest<< Poprzednia .. Myślę, że źle rozumie tę wartość ze znacznikiem początkowym z powodu obecności<< w tekście..
Szczegóły LogCat to:
<code>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) </code>
Mam nadzieję, że wyjaśniłem mój problem.
RozwiązanieIsnpired byMartina Podejście polegające na zamianie najpierw otrzymanych danych na ciągi znaków, udało mi się rozwiązać problem w rodzaju podejścia mieszanego.
Konwertuj otrzymaneStrumień wejściowywartość do ciąg i zastąpił błędne znaki * (lub cokolwiek chcesz): w następujący sposób
<code>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(); } </code>
Teraz mam ciąg, który zawiera poprawne dane XML (dla mojego przypadku), więc po prostu użyj normalnego XmlPullParser, aby go przeanalizować, zamiast ręcznie analizować go samodzielnie:
<code>XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); factory.setNamespaceAware(false); XmlPullParser parser = factory.newPullParser(); parser.setInput(new StringReader(xmlAsString.toString())); </code>
Mam nadzieję, że to komuś pomoże!