0

AndroidアプリケーションでSAXパーサーを使用して、一度にいくつかのフィードを読み取ります。スクリプトは次のように実行されます。

                     // Begin FeedLezer
                    try {

                        /** Handling XML **/
                        SAXParserFactory spf = SAXParserFactory.newInstance();
                        SAXParser sp = spf.newSAXParser();
                        XMLReader xr = sp.getXMLReader();

                        /** Send URL to parse XML Tags **/
                        URL sourceUrl = new URL(
                            BronFeeds[i]);

                        /** Create handler to handle XML Tags ( extends DefaultHandler ) **/
                        Feed_XMLHandler myXMLHandler = new Feed_XMLHandler();
                        xr.setContentHandler(myXMLHandler);
                        xr.parse(new InputSource(sourceUrl.openStream()));

                    } catch (Exception e) {
                        System.out.println("XML Pasing Excpetion = " + e);
                    }
                     sitesList = Feed_XMLHandler.sitesList;

                    String titels = sitesList.getMergedTitles();

そして、ここにFeed_XMLHandler.javaFeed_XMLList.javaがあります。これらは、基本的に両方ともWebから取得したものです。

ただし、このコードは失敗することがあります。いくつか例を示します。

http://imm.io/media/2I/2IAs.jpg ここでは非常にうまくいきます。アポストロフィも認識して表示します。開いている記事をクリックしても、ほとんどすべてのテキストが表示されるので、それはすべて良いことです。ソースフィードはこちらです。フィードを制御できません。

http://imm.io/media/2I/2IB1.jpgここでは、うまくいきません。ïは表示されますが、アポストロフィで窒息します(Waaromの後に「NORAD」があるはずです)。ここ

http://imm.io/media/2I/2IBQ.jpgこれは最悪です。ご覧のとおり、タイトルにはアポストロフィのみが表示されていますが、「blablabla」であると想定されています。また、テキストは行の途中で終わり、引用符には特殊文字は含まれていません。フィードはこちら

いずれの場合も、フィードを制御することはできません。スクリプトは特殊文字を窒息させると思います。SAXがすべての文字列を正しくフェッチするようにするにはどうすればよいですか?

誰かがこれに対する答えを知っているなら、あなたは本当に私をたくさん助けてくれます:D

前もって感謝します。

4

1 に答える 1

5

これはXercesのFAQからです。

SAXパーサーが一部の文字データを失うのはなぜですか、またはデータがいくつかのチャンクに分割されるのはなぜですか?SAXのドキュメントを読むと、パーサーの効率と入力バッファリングに関係する理由から、SAXが連続したテキストを文字への複数の呼び出しとして配信する場合があることがわかります。次の文字以外のイベントまでテキストを蓄積するなどして、これに適切に対処するのはプログラマーの責任です。

あなたのコードは、多くのXML解析チュートリアルの1つ(ここにあるような)から非常によく適合していますこれで、チュートリアルはすべてうまくいきましたが、非常に重要なことについては言及されていません...

ここでこの部分に注意してください...

    public void characters(char[] ch, int start, int length)
            throws SAXException
    {
              if(in_ThisTag){
                     myobj.setName(new String(ch,start,length))
              }
    }

この時点で、ブール値をチェックして、下にあるタグをマークし、作成したある種の値を設定しているに違いありclassませんか?またはそのようなもの....

ただし、問題は、(バッファリングされている)SAXパーサーが、タグ間のすべての文字を一度に取得する必要がないことです。たとえば<tag> Lorem Ipsum...really long sentence...</tag>、SAXパーサー呼び出しcharacters関数がチャンクである場合などです。

したがって、ここでの秘訣は、文字列変数に値を追加し続けset、タグが終了したときに実際に(またはコミットして)構造に追加することです...(つまりendElement

@Override
public void endElement(String uri, String localName, String qName)
        throws SAXException {

    currentElement = false;

    /** set value */
    if (localName.equalsIgnoreCase("tag"))
            {
        sitesList.setName(currentValue);
                    currentValue = ""; //reset the currentValue
            }

}

@Override
public void characters(char[] ch, int start, int length)
        throws SAXException {

    if (in_Tag) {
        currentValue += new String(ch, start, length); //keep appending string, don't set it right here....maybe there's more to come.
    }

}

また、StringBuilder追加に使用すると効率が上がるので、使用したほうがよいでしょう。

それが理にかなっていることを願っています!これここをチェックしなかった場合

于 2010-12-24T18:55:09.990 に答える