2012-03-29 2 views
0

ISO 8859/1ストリームとしてフォーマットされたサックスパーサーにソケットを供給しています。非常に頻繁に無効な文字があり、行と列のあるSAXParseExceptionが発生します。そのため、その時点でデータが何であるかを知る必要があります。Java XML:ソケットから解析するときに部分的なXMLツリーのコピーを保持する

は、もともとのデータを処理した行は次の通りであった:

InputSource is = new InputSource(new InputStreamReader(socket.getInputStream(), "ISO8859_1")); 
XMLReader reader = XMLReaderFactory.createXMLReader(); 
reader.setContentHandler(new ResponseParseHandler(etc, id)); 
reader.parse(is); 

問題は、私はこの出来事のイベントの後のデータを得ることができないということですので、私は大規模なバイトバッファに読み取るために、それを変更し、変換しますそれを文字列に変換し、そのデータをStringReaderで解析します。残念ながら、ソケットから来るデータは、長時間に渡って小さなまとまりに広がっているため、最初に接続するときにルートタグで始まりますが、終了タグなしで数千のメッセージが分離して表示されます。

これらの文字列が最初に来るときに私はこれらの文字列を個別に解析しているので、終了タグがないというエラーがあり、次のエラーは基本タグを持たないためエラーです。ストリームがまだ開いていると仮定すると、これはソケットでは発生しません。

おそらく私はこれらの文字列を別のリーダ/ライターに送ることができますが、データブロックが何であったかエラーの時刻

本当にシンプルなものがありますか?

+0

これは、データをストリームとしてXMLとして取得し、エラーが発生した場所を確認することを意味します。 –

+0

はい、それは私が望むものです。 – Woody

答えて

1

前回私がこれに似た問題を抱えたとき、私はSplittingWriterで解決しました。これは他の2つのデコレータスタイルのクラスであり、何かがSplittingWriterに "書き込んだ"とき、それは単にその2つの基礎となる両方のWriterの両方に書き込み呼び出しを委任しました。あなたのケースでは

、あなたはInputStreamReaderを実装して、あなたは、現時点で代わりに使用しているInputStreamReaderInputSourceに渡すことになるSplittingInputStreamReader、のような何かをしたいと思います。

そのコンストラクタでは、SplittingInputStreamReaderは現在のInputStreamReaderと他のオブジェクトを取ります。Fooとします。 SplittingInputStreamReaderreadメソッドを実装すると、読み取った呼び出しを基になるInputStreamReaderに委任し、その呼び出しの結果をFooにプッシュし、呼び出しの結果を呼び出したものに戻します。だから、int read()メソッドの実装のようなものになるだろう:その方法

 

    @Override 
    public int read() { 
     int r = this.inputStreamReader.read(); 
     this.foo.submit(r); 
     return r; 
    } 
 

あなたはSplittingInputStreamReaderを経由して読んで、あなたも書き込みは、あなたがFooにまともなインターフェースを与えたと仮定すると停止した場所を見ることができるよう、Fooに書き込みます。 (例えばMyInputStreamReader)

 

Foo streamCapture = new Foo(); 
SplittingInputStreamReader streamReader = new SplittingInputStreamReader(
    new InputStreamReader(socket.getInputStream(), "ISO8859_1"), streamCapture); 
InputSource is = new InputSource(streamReader); 
XMLReader reader = XMLReaderFactory.createXMLReader(); 
reader.setContentHandler(new ResponseParseHandler(etc, id)); 
reader.parse(is); 
// After parse, if there was an error, check what is in Foo streamCapture 
 
+0

「org.apache.commons.io.input.TeeInputStream」のようなもの – artbristol

+0

ちょっと見てみました。その場合、FooはOutputStreamの "branch"に相当します。 – Jon

+0

計画のように聞こえて、どこに向かいましたか、あまりにも遠くに行きました!感謝します。 – Woody

1

あなたはあなたが必要とするコンテンツへの参照を保持し、独自にInputStreamReaderカスタムのimplを提供することができ、ための方法を提供する:最後に、SplittingInputStreamReaderFooを実施した後、あなたのコードは次のようになりますデコードされたコンテンツまたは最後に1024バイトのデコードされたコンテンツ(またはキャップされた量)を取得します。

既存のInputStreamReaderを既に行っていることをさせてください。カスタムクラスの追加のロジックでラップして、それを渡してInputSourceを作成してください。