Tengo una situación en la que llamo a un servicio web y me devuelve algo de HTML en un sobre XML. como:Android org.xmlpull.v1.XmlPullParserException al analizar 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>
tengo que recuperar los enlace-a-ant-post & enlace-a-lado-post enlaces .. para que pueda obtener más datos a través de estos enlaces.
Estoy usando XmlPullParser para analizar el XML/HTML proporcionado anteriormente. Para obtener los enlaces para próximos artículos/prev, que estoy haciendo de la siguiente manera:
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;
}
}
Se lanza XmlPullParserException en la ejecución de parser.nextText() ... y el valor del elemento de texto en este el tiempo es < < Anterior .. creo que no entiende este valor con etiqueta de inicio debido a la presencia de < < en el texto ..
detalle LogCat es:
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)
espero haber aclarado mi problema.
Solución
Isnpired por Martin's enfoque de convertir los datos recibidos primero en cadena, he conseguido mi problema en una especie de enfoque mixto.
Convertir valor de la recibida InputStream 's de la cadena y reemplazado los caracteres erróneos con * (o lo que usted desee): la siguiente manera
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(); }
Ahora tengo una cadena que contiene correcta datos XML (para mi caso), por lo que sólo utilizan el XmlPullParser normal a analizarlo en lugar de analizar manualmente a mí mismo:
XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); factory.setNamespaceAware(false); XmlPullParser parser = factory.newPullParser(); parser.setInput(new StringReader(xmlAsString.toString()));
Espero que esto ayude a alguien!
gracias por la explicación ... en realidad no tengo control sobre el servicio web, así que no puedo cambiar lo que devuelve ... usar expresiones regulares suena bien, pero el problema surge cuando intento leer los datos usando _parser.nextText() _ .. así que creo que Regex no se puede usar tan bien porque primero tendré que obtener el texto antes de analizarlo a través de expresiones regulares ... pero si crees que se puede hacer, ¿puedes por favor darme algunos ejemplo amplio? eso seria genial. – Aamir
¡Me alegra ayudar! En realidad, me refería a analizar el XML completo manualmente, es decir, no utilizar el analizador XML en absoluto (ya que no es XML válido que está analizando). –
ok i umnderstand now .. pero ¿cómo propondrías tal análisis manual? Estoy buscando un ejemplo ... ya que estoy muy atascado – Aamir