2

Java を使用して、リモート デバイスによって生成されたイベント ドライブ XML の進行中のストリームを解析しようとしています。2 つのイベントの簡単なサンプルを次に示します。

<?xml version="1.0"?>
<Event> DeviceEventMsg
<Param1>SomeParmValue</Param1>
</Event>
<?xml version="1.0"?>
<Event> DeviceEventMsg
<Param1>SomeParmValue</Param1>
</Event>

DOM よりも SAX の方が適しているように思えます。これは進行中のストリームであるためです。ただし、私は Sax に詳しくありません。XML の構造について怒鳴らないでください。私はそれを既に知っており、変更することはできません。

はい、デバイスはすべてのイベントの前に xml ディレクティブを送信します。私の最初の問題は、2 番目の xml 処理命令が SAX パーサーをクラッキングしていることです。

誰かがそれを回避する方法を提案できますか?


私がこれまで使用していた、2 番目の xml 処理命令で鳴っているコードは次のとおりです。

public class TestMe extends HandlerBase {
    public void startDocument () throws SAXException
    {
        System.out.println("got startDocument");
    }

    public void endDocument () throws SAXException
    {
        System.out.println("got endDocument");
    }

    public void startElement (String name, AttributeList attrs) throws SAXException
    {
        System.out.println("got startElement");
    }

    public void endElement (String name) throws SAXException
    {
        System.out.println("got endElement");
    }

    public void characters (char buf [], int offset, int len) throws SAXException
    {
        System.out.println("found characters");
    }

    public void processingInstruction (String target, String data) throws SAXException
    {
        System.out.println("got processingInstruction");
    } 

    public static void main(String[] args) {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        try {
            SAXParser saxParser = factory.newSAXParser();
            // using a file as test input for now
            saxParser.parse( new File("devmodule.xml"), new TestMe() );

        } catch (Throwable err) {
            err.printStackTrace ();
        }
    }
}
4

5 に答える 5

1

特に複数のxml宣言に関するもう1つの提案。はい、これは ILLEGAL xml であるため、適切なパーサーはデフォルト モードを使用してバーフします。しかし、一部のパーサーには代替の「マルチドキュメント」モードがあります。たとえば、Woodstox にはこれがあるので、チェックアウトできます。

http://www.cowtowncoder.com/blog/archives/2008/04/entry_66.html

基本的に、入力が「複数の xml ドキュメント」(ParsingMode.PARSING_MODE_DOCUMENTS) の形式であることを (入力ファクトリを介して) パーサーに伝える必要があります。

その場合、複数の xml 宣言を受け入れ、それぞれが新しいドキュメントの開始を示します。

于 2009-02-24T19:12:04.013 に答える
1

SAX の代わりにStAXを使用してみてください。StAX を使用すると柔軟性が大幅に向上し、XML ストリーミングのより優れたソリューションとなります。StAX の実装はほとんどありません。codehausの実装に非常に満足していますが、Sunの実装もあります。それはあなたの問題を解決するかもしれません。

于 2008-10-13T17:13:29.003 に答える
0

開始要素と終了要素 System.out.println() の名前を出力すると、次のようになります。

got startDocument got startElement Event found characters found characters got startElement Param1 found characters got endElement Param1 found characters got endElement イベント org.xml.sax.SAXParseException: 「[xX][mM][lL]」に一致する処理命令ターゲットは許可されていません。...

だから私は2番目だと思います

<?xml version="1.0"?>

endDocument を取得しないと、パーサーの問題が発生します。

于 2008-10-13T21:31:10.200 に答える
0

RE: SAXException をキャッチして、ある XML ドキュメントの最後に到達し、別の XML ドキュメントの最初に到達したことを判断するという Simon の提案は、問題のあるアプローチだと思います。別のエラーが (何らかの理由で) 発生した場合、例外がスローされたのは XML の誤りによるものなのか、ドキュメントの最後に達したためなのかを判断することはできません。

問題は、パーサーが XML 文書を処理するためのものであることです。複数の XML ドキュメントのストリームではありません。着信データ ストリームを手動で解析するコードを記述し、単一の XML ドキュメントを含む個々のストリームに分割することをお勧めします。次に、これらのストリームを XML パーサーにシリアルで渡します (これにより、イベントの順序が保証されます)。

于 2008-10-13T22:12:41.693 に答える
0

これを追加すると:

catch(SAXException SaxErr){
        System.out.println("ignore this error");
    }

他のキャッチの前に、この特定のエラーをキャッチします。次に、デバイスを再度開くか、静的ファイルの場合は、ファイル内にいる場合に追跡する必要があります。

または、イベント イベントの終了時に、デバイス/ファイルを閉じてから、次のイベントのために再度開きます。

于 2008-10-13T21:49:22.287 に答える