2009-12-11 9 views
6

RSSとAtomファイルの解析時にSAXに問題が発生しました。彼によると、Item要素からのテキストがアポストロフィやアクセント付きの文字で切り捨てられているかのようです。エンコードにも問題があるようです。Saxの解析とエンコーディング

私はSAXに試してみましたが、私は切り捨てを行っていますが、それ以上は掘り下げることができませんでした。誰かがこれに前に取り組んでいるなら、いくつかの提案を感謝します。

これはContentHandlerの中で使われているコードです:

public void characters(char[], int start, int end) throws SAXException { 
// 
    link = new String(ch, start, end); 

編集:私はJavaはUnicodeで動作します知っているようにエンコードの問題は、バイト配列に情報を格納する原因である可能性があります。

+1

DOM解析は遅く、メモリが集中するため、ほとんどの人はSAXを使用します。しかし、もし文書構造が複雑であれば、SAXの構文解析は非常に難しくなりますが、SAX解析が困難または低すぎると、vtd-xmlは最高の効率性とメモリ使用量の組み合わせに最適です。 –

答えて

13

characters()メソッドは、1回のパスでテキスト要素の完全な文字内容を保証するものではありません。フルテキストはバッファ境界にまたがることがあります。開始イベントと終了イベントの間で、文字を自分でバッファリングする必要があります。

StringBuilder builder; 

public void startElement(String uri, String localName, String qName, Attributes atts) { 
    builder = new StringBuilder(); 
} 

public void characters(char[] ch, int start, int length) { 
    builder.append(ch,start,length); 
} 

public void endElement(String uri, String localName, String qName) { 
    String theFullText = builder.toString(); 
} 
+0

追加しているStringBuilderを同期させるべきではありませんか?またはStringBufferを使用しますか? – ruchirhhi

+0

同期は必要ありません。SAX解析はシングルスレッドであり、一般に、解析される各ドキュメントに対して個別のContentHandlerを使用します。 ContentHandlerを再利用したい場合は、ThreadLocalやその他のプーリングメカニズムを使用するのが最良です。複数の解析ストリームを別々のスレッドで同時に処理できるContentHandlerを作成するのは非常に難しいでしょう。どの文書? –

+0

ありがとう!私の日を救った。 –

1

どのように入力をSAXに渡しますか? InputStream(推奨)またはReaderとして?したがって、あなたのバイト[]から始めて、ByteArrayInputStreamを使ってみてください。

+0

Egon私はChannelクラスを見て、XMLReaderが使用されています。 ContentHandlerが設定され、parse()メソッドが呼び出されます。それはそうだ。 –

+0

私のコードを見ることができます:http://cdk.git.sourceforge.net/git/gitweb.cgi?p=cdk/cdk;a=blob;f=src/main/org/openscience/cdk/ io/CMLReader.java; h = 490743955939b8a003c95769c3261b06eb341842; hb = HEAD –

+0

ところで、どのXMLパーサーを使用していますか?私がリンクしたばかりのコードでは、3つの異なるXMLパーサが使用できます。デフォルトでは、Javaのバージョンが新しく、次にAelfred、最後のXercesがデフォルトとなります。 –

5

XML entitiesはSAXで特別なイベントを生成します。 LexicalHandlerでキャッチすることはできますが、一般的には必要ありません。しかし、これはを説明します。charactersイベントはタグごとに1つしか受け取らないと想定できません。他の回答で説明されているようにバッファを使用してください。 hello&worldはシーケンス

  • のstartElement
  • 文字ハロー
  • startEntity
  • 文字&
  • からendEntity
  • 文字の世界を生成します例えば

さらに詳しい例が必要な場合は、Auxialiary SAX interfaceをご覧ください。その他の特別イベントは、外部エンティティ、コメント、CDATAなどです。

関連する問題