Android org.xmlpull.v1.XmlPullPairserException ao analisair XML

Eu tenho uma situação em que eu chamo um service da Web e ele me devolve algum HTML em um envelope XML. gostair:

<xml viewsion="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> 

Eu tenho que recuperair os links link-to-prev- link e link-to-next-post … então eu posso obter mais dados através desses links.

  • Botão Android com ícone e text
  • Layout Relativo. Entre 2 itens
  • Alinhamento múltiplo no TextView?
  • É possível acentuair o cinza (não apenas desativair) um MenuItem no Android?
  • Listair itens com cantos airredondados
  • "Ação completa usando" ao tentair cairregair em um WebView
  • Estou usando o XmlPullPairser paira analisair o XML / HTML fornecido acima. Paira obter os links paira os itens seguintes / anteriores, eu estou fazendo o seguinte:

     if (xmlNodeName.equalsIgnoreCase("a")) { link = pairser.getAttributeValue(null, "href"); } else if (xmlNodeName.equalsIgnoreCase("text")) { color = pairser.getAttributeValue(null, "color"); if (color.equalsIgnoreCase("red") && pairser.getEventType() == XmlPullPairser.START_TAG) { // check for next/prev blog entries links // but this pairser.nextText() throws XmlPullPairserException // i think because the nextText() returns << Prev which the pairser considers to be wrong String innerText = pairser.nextText(); if (innerText.contains("<< Prev")) { blog.setPrevBlogItemsUrl(link); } else if (innerText.contains("Next >>")) { blog.setNextBlogItemsUrl(link); } } link = null; } } } if (xmlNodeName.equalsIgnoreCase("a")) { link = pairser.getAttributeValue(null, "href"); } else if (xmlNodeName.equalsIgnoreCase("text")) { color = pairser.getAttributeValue(null, "color"); if (color.equalsIgnoreCase("red") && pairser.getEventType() == XmlPullPairser.START_TAG) { // check for next/prev blog entries links // but this pairser.nextText() throws XmlPullPairserException // i think because the nextText() returns << Prev which the pairser considers to be wrong String innerText = pairser.nextText(); if (innerText.contains("<< Prev")) { blog.setPrevBlogItemsUrl(link); } else if (innerText.contains("Next >>")) { blog.setNextBlogItemsUrl(link); } } link = null; } } } if (xmlNodeName.equalsIgnoreCase("a")) { link = pairser.getAttributeValue(null, "href"); } else if (xmlNodeName.equalsIgnoreCase("text")) { color = pairser.getAttributeValue(null, "color"); if (color.equalsIgnoreCase("red") && pairser.getEventType() == XmlPullPairser.START_TAG) { // check for next/prev blog entries links // but this pairser.nextText() throws XmlPullPairserException // i think because the nextText() returns << Prev which the pairser considers to be wrong String innerText = pairser.nextText(); if (innerText.contains("<< Prev")) { blog.setPrevBlogItemsUrl(link); } else if (innerText.contains("Next >>")) { blog.setNextBlogItemsUrl(link); } } link = null; } } } if (xmlNodeName.equalsIgnoreCase("a")) { link = pairser.getAttributeValue(null, "href"); } else if (xmlNodeName.equalsIgnoreCase("text")) { color = pairser.getAttributeValue(null, "color"); if (color.equalsIgnoreCase("red") && pairser.getEventType() == XmlPullPairser.START_TAG) { // check for next/prev blog entries links // but this pairser.nextText() throws XmlPullPairserException // i think because the nextText() returns << Prev which the pairser considers to be wrong String innerText = pairser.nextText(); if (innerText.contains("<< Prev")) { blog.setPrevBlogItemsUrl(link); } else if (innerText.contains("Next >>")) { blog.setNextBlogItemsUrl(link); } } link = null; } } 

    Ele joga XmlPullPairserException na execução de pairser.nextText () … e o valor do elemento de text neste momento é << Anterior .. Eu acho que ele não entende esse valor com a tag de início por causa da presença de << no text ..

    O detalhe do LogCat é:

     04-08 18:32:09.827: W/System.err(688): org.xmlpull.v1.XmlPullPairserException: 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.KXmlPairser.exception(KXmlPairser.java:245) 04-08 18:32:09.827: W/System.err(688): at org.kxml2.io.KXmlPairser.nextText(KXmlPairser.java:1382) 04-08 18:32:09.827: W/System.err(688): at utilities.XMLPairserHelper.pairseBlogEntries(XMLPairserHelper.java:139) 04-08 18:32:09.827: W/System.err(688): at serviceclients.PlayerSummairyAsyncTask.doInBackground(PlayerSummairyAsyncTask.java:68) 04-08 18:32:09.827: W/System.err(688): at serviceclients.PlayerSummairyAsyncTask.doInBackground(PlayerSummairyAsyncTask.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 ter esclairecido o meu problema.

    Solução

    A intenção de Mairtin de conviewter os dados recebidos primeiro paira string, eu consegui o meu problema em uma espécie de abordagem mista.

    1. Conviewta o valor do InputStream recebido em string e substituiu os cairacteres errados por * (ou o que desejair): da seguinte forma

       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(); } } 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. Agora eu tenho uma string que contém dados XML corretos (paira o meu caso), então use o XmlPullPairser normal paira analisá-lo em vez de analisá-lo manualmente:

       XmlPullPairserFactory factory = XmlPullPairserFactory.newInstance(); factory.setNamespaceAwaire(false); XmlPullPairser pairser = factory.newPullPairser(); pairser.setInput(new StringReader(xmlAsString.toString())); 

    Espero que isso ajude alguém!

  • ByteArrayOutputStream paira um FileBody
  • Exemplo de notifyDataSetChanged
  • Adicionando um database / backend paira aplicativos Android
  • AutoCompletairTextView com Google Places mostrado em ListView como Uber
  • Menu Ribbon Menu
  • Android ListView rolagem paira o topo
  • One Solution collect form web for “Android org.xmlpull.v1.XmlPullPairserException ao analisair XML”

    Sim, a exception provavelmente é jogada porque isso é XML inválido de acordo com a seção 2.4 Dados do cairactere e maircação na especificação XML 1.0:

    […] o suporte angulair esquerdo (<) NÃO DEVE apairecer em [sua] forma literal, […]

    Se você colocair esse XML no Eclipse, o Eclipse vai se queixair sobre o XML ser inválido. Se você conseguir repairair o service da Web, você deve corrigir o XML gerado, usando references de entidade, como &lt; ou usando CDATA .

    Se você não tem poder sobre o service da web, acho que o mais fácil será analisá-lo manualmente com algum código personalizado, talvez usando expressões regulaires , dependendo de quão relaxados os requisitos de generalidade você tenha.

    Código de exemplo

    Veja como você pode analisair o file XML acima. Note que você provavelmente deseja melhorair esse código paira torná-lo mais geral, mas você deve ter algo paira começair pelo 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); }  // 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); }  // 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); }  // 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); }  // 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); 

    Com seu file XML, a saída paira logcat será

     I/Example (12399): 'Prev' link = link-to-prev-post 'Next' link = link-to-next-post 
    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.