2

そして、「&」ではありません

SAXParser オブジェクトを使用して、実際の XML を解析します。

これは通常、XMLReader.Parse メソッドに URL を渡すことによって行われます。私の XML は Web サービスへの POST 要求から来ているため、その結果を文字列として保存し、StringReader / InputSource を使用してこの文字列を XMLReader.Parse メソッドにフィードバックしています。

しかし、XMLstring の 2001 文字目で奇妙なことが起こっています。
ドキュメント ハンドラーの 'characters' メソッドは、startElement メソッドと endElement メソッドの間で 2 回呼び出され、文字列 (この場合はプロジェクト タイトル) を効果的に 2 つに分割します。文字メソッドでオブジェクトをインスタンス化しているため、1 つではなく 2 つのオブジェクトを取得しています。

この行では、文字列に約 2000 文字が含まれており、「文字」が 2 回発生し、「Lower」と「Level」の間で中断されます。

<title>SUMC-BOOKSTORE, LOWER LEVEL RENOVATIONS</title>

StringReader / InputSource の回避策をバイパスして、フラットな XML ファイルを XMLReader.Parse にフィードすると、まったく問題なく動作します。

StringReader や InputSource に関する何かが、どういうわけかこれを台無しにしています。

これは、SAXParser を使用して XML 文字列を取得し、解析する私の方法です。

    public void parseXML(String XMLstring) {
    try {
        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser sp = spf.newSAXParser();
        XMLReader xr = sp.getXMLReader();
        xr.setContentHandler(this);

        // Something is happening in the StringReader or InputSource 
        // That cuts the XML element in half at the 2001 character mark.

        StringReader sr = new StringReader(XMLstring);
        InputSource is = new InputSource(sr);
        xr.parse(is);


    } catch (IOException e) {
        Log.e("CMS1", e.toString());
    } catch (SAXException e) {
        Log.e("CMS2", e.toString());
    } catch (ParserConfigurationException e) {
        Log.e("CMS3", e.toString());
    }
}

XML 文字列のこの時点に到達したときに、「文字」が 2 回発火しないようにする方法についてのアイデアをいただければ幸いです。

または、POST 要求を使用して URL を Parse 関数に渡す方法を教えてください。

ありがとうございました。

4

4 に答える 4

5

ドンロビーが言ったように、パーサーがstartElementとendElementの間でcharactersメソッドを複数回呼び出すことは完全に合法です。しかし、それはまったく「誤動作」ではなく、それが起こらないように物事をいじくり回そうとすべきではありません。パーサーは2000文字のバッファーを使用しているようですが、テキストノードを部分に分割する理由は他にもあります。

あなたがすべきことは、文字メソッドでデータを蓄積し、後でそれを処理することです。ノードのすべての文字データを蓄積したことが確実な場合は、endElementメソッドでデータを処理します。

于 2010-03-31T04:12:11.510 に答える
2

SAXParser の startElement と endElement の間で、characters メソッドが複数回起動することは正当です。実装で処理されていない場合は、使用されている ContentHandler に誤ってコード化された文字メソッドが含まれている可能性があります。

コード スニペットから、「this」を ContentHandler として渡しているため、不正な文字メソッドがコードの他の場所にあると思います。そのコードを投稿してください。修正をお手伝いできるかもしれません。

Javadocを参照して、フレーズに注意してください

SAX パーサーは、連続するすべての文字データを 1 つのチャンクで返すか、複数のチャンクに分割する場合があります。

この Javadoc は ContentHandler 用です。DocumentHandler を使用しているようです。これは、ContentHandler を支持して廃止されました。しかし、DocumentHandler の javadoc には同じ言語が含まれています。

于 2010-03-30T23:39:18.727 に答える
1

お二方、ご回答ありがとうございました。あなたの助けを借りて、私は問題を解決することができました。

オンラインチュートリアルで学んだ「文字」メソッド内で実際の処理を行っていました。

処理を endElement メソッドに移すことで、「文字」が何回発射されても、単純に文字を連結して文字列にすることができました。

ブール値の betweenTags を設定し、startElement の間はこれを true に、endElement の最後で false にすることで、これを実現しました。

文字の中に、私は追加しました

if (betweenTags) accumulation += chars;

累積文字列は、startElement の末尾の "" に設定されます。

壊れた要素はありません。

ありがとう!

于 2010-03-31T16:12:07.487 に答える