2012-04-08 19 views
7

私はWebサービスを呼び出し、XMLエンベロープにHTMLを返します。以下のような:XMLを解析中にAndroid org.xmlpull.v1.XmlPullParserExceptionが発生する

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

私はこれらのリンク経由リンク対前のポスト & リンクツー隣ポストリンク..ので、私が得ることができるより多くのデータを取得する必要があります。

私は上記のXML/HTMLを解析するためにXmlPullParserを使用しています。次のように次/前の項目へのリンクを取得するには、私がやっています:

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 ...と、この時のテキスト要素の値をスローします時間は

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) 

私は私の問題を明確にしたいと思う。文字列に最初に受信したデータを変換するMartin'sアプローチによってIsnpired

ソリューション

は、私は、混合アプローチの一種で私の問題を管理します。

  1. 文字列に受信のInputStreamの値に変換し、*(またはものは何でもあなたが望む)との誤った文字を置き換え:

    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. を次のように今私は正しい含む文字列を持っています私の場合はXMLデータですので、通常のXmlPullParserを使用して手動で解析するのではなく、解析することができます。

これは誰かを助けることを願っています!

答えて

6

はい、それはXML 1.0仕様にセクション2.4 Character Data and Markupあたりとして無効なXMLであるため、例外がスローされ、おそらく:

[...]左アングルブラケット(<)その[に現れてはなりません]リテラルフォーム[...]

このXMLをEclipseに入れると、EclipseはXMLが無効であると訴えるでしょう。 Webサービスを修正できる場合は、&lt;などのエンティティ参照を使用するか、CDATAを使用して、生成されたXMLを修正する必要があります。

Webサービスを利用する権限がない場合は、一般的な要件が緩和されているかどうかによって、おそらくregular expressionsを使用してカスタムコードで手動で解析するのが最も簡単だと思います。

例コード

上記のXMLファイルを解析する方法は次のとおりです。あなたのXMLファイルで

// 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); 

、logcatへの出力が

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

になります:あなたは、おそらくそれがより一般的にするために、このコードを改善したい、しかし、あなたは、少なくともで開始する何かを持っている必要があることに注意してください説明のためにありがとう...実際に私はWebサービスを制御できないので返されるものを変更することはできません...正規表現を使用すると良いですが_parser.nextText()_を使用してデータを読み取ろうとすると問題が発生します。だから私は正規表現を使用することはできませんもbcoz私は最初正規表現を介してそれを解析する前にテキストを取得する必要があります..しかし、あなたがそれを行うことができます私はいくつかの十分な例??それは素晴らしいだろう。 – Aamir

+0

私は助けてうれしい!私は実際にXML全体を手動で解析することを指していました。つまり、XMLパーサーをまったく使用していない(解析している有効なXMLではないためです)。 –

+0

ok私はすぐに勉強しました..しかし、どうやってこのような手動の解析を提案しますか?私は例を探しています。ひどく詰まっています。 – Aamir

関連する問題