parsingXML时Android org.xmlpull.v1.XmlPullParserException

我有一个情况,我打电话给一个Web服务,它返回一些XML信封中的HTML。 喜欢:

<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来parsing上面提供的XML / HTML。 要获得下一个/ prev项目的链接,我正在做如下:

 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; } } 

它会抛出parser.nextText ()执行XmlPullParserException …此时文本元素的值是<< 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) 

我希望我已经澄清了我的问题。

马丁的方法是将接收到的数据首先转换为string,我用一种混合的方法处理了我的问题。

  1. 将接收到的InputStream的值转换为string,并将错误字符replace为*(或任何您所希望的):如下所示

     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(); } 
  2. 现在我有一个string包含正确的XML数据(对于我的情况),所以只需使用普通的XmlPullParser来parsing它,而不是手动parsing它自己:

     XmlPullParserFactory factory = XmlPullParserFactory.newInstance(); factory.setNamespaceAware(false); XmlPullParser parser = factory.newPullParser(); parser.setInput(new StringReader(xmlAsString.toString())); 

希望这可以帮助别人!

Solutions Collecting From Web of "parsingXML时Android org.xmlpull.v1.XmlPullParserException"

是的,根据XML 1.0规范中的2.4字符数据和标记 ,可能会抛出exception,因为这是无效的XML:

左angular括号(<)不得以[字面]forms出现,[…]

如果你把这个XML放在Eclipse中,Eclipse会抱怨XML是无效的。 如果您能够修复Web服务,则应该使用实体引用(如&lt; 或通过使用CDATA 。

如果你对Web服务没有权力,我认为最简单的方法就是用一些自定义代码手工parsing,也许使用正则expression式 ,这取决于你有多宽松的要求。

示例代码

以下是如何parsing上面的XML文件。 请注意,您可能希望改进此代码以使其更通用,但您至less应该有一些事情要做:

  // Read the XML into a StringBuilder so we can get get a Matcher for the // whole XML InputStream xmlResponseInputStream = // Get InputStream to XML somehow InputStreamReader isr = new InputStreamReader(xmlResponseInputStream); BufferedReader br = new BufferedReader(isr); StringBuilder xmlAsString = new StringBuilder(512); String line; try { while ((line = br.readLine()) != null) { xmlAsString.append(line); } } catch (IOException e) { e.printStackTrace(); } // Look for links using a regex. Assume the first link is "Prev" and the // next link is "Next" Pattern hrefRegex = Pattern.compile("<a href=\"([^\"]*)\">"); Matcher m = hrefRegex.matcher(xmlAsString); String linkToPrevPost = null; String linkToNextPost = null; while (m.find()) { String hrefValue = m.group(1); if (linkToPrevPost == null) { linkToPrevPost = hrefValue; } else { linkToNextPost = hrefValue; } } Log.i("Example", "'Prev' link = " + linkToPrevPost + " 'Next' link = " + linkToNextPost); 

用你的XML文件,logcat的输出将会是

 I/Example (12399): 'Prev' link = link-to-prev-post 'Next' link = link-to-next-post