Ho una situazione in cui io chiamo un servizio Web e mi restituisce del codice HTML in una busta XML. come:Android org.xmlpull.v1.XmlPullParserException durante l'analisi 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>
devo recuperare i link-to-prev-post & link-to-next-post link .. così posso ottenere più dati attraverso questi collegamenti.
Sto usando XmlPullParser per analizzare l'XML/HTML fornito sopra. Per ottenere i link per gli articoli/prev next, sto facendo come segue:
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;
}
}
Getta XmlPullParserException in esecuzione di parser.nextText() ... e il valore dell'elemento di testo a questo il tempo è < < Prec .. penso che fraintende questo valore con tag di apertura a causa della presenza di < < nel testo ..
dettaglio 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 [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)
Spero di aver chiarito il mio problema.
Soluzione
Isnpired da Martin's approccio di convertire i dati ricevuti prima a stringa, sono riuscito il mio problema in una sorta di approccio misto.
Convertire il valore ricevuto InputStream s' a stringa e sostituito i caratteri errati con * (o qualsiasi altra cosa che si desidera): come segue
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(); }
Ora ho una stringa che contiene corretta dati XML (per il mio caso), quindi basta utilizzare il XmlPullParser normale per analizzare invece di parsing manualmente io stesso:
XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); factory.setNamespaceAware(false); XmlPullParser parser = factory.newPullParser(); parser.setInput(new StringReader(xmlAsString.toString()));
Spero che questo aiuti qualcuno!
grazie per la spiegazione ... in realtà non ho alcun controllo sul servizio web, quindi non posso cambiare cosa è ritornato ... usare le espressioni regolari sembra buono ma il problema sorge quando provo a leggere i dati usando _parser.nextText() _ .. Quindi penso che la regex non possa essere usata come bene bcoz dovrò prima ottenere il testo prima di analizzarlo attraverso la regex .. ma se pensi che possa essere fatto allora puoi darmi qualche cosa ampio esempio ?? sarebbe grandioso. – Aamir
Sono felice di aiutare! In realtà mi stavo riferendo all'analisi dell'intero XML manualmente, cioè non utilizzando affatto il parser XML (poiché non si tratta di XML valido che si sta analizzando). –
ok ho capito adesso .. ma come proporresti un simile parsing manuale? sto cercando un esempio ... sono bloccato male – Aamir