Frage

Ich suche einen XML -Parser, der anstatt von einem InputStream oder InputSource analysiert zu werden, ermöglicht stattdessen Textblöcke in den Parser. ZB ich möchte so etwas wie Folgendes:

public class DataReceiver {
    private SAXParser parser = //...
    private DefaultHandler handler = //...

    /**
     * Called each time some data is received.
     */
    public void onDataReceived(byte[] data) {
        parser.push(data, handler);
    }
}

Der Grund dafür ist, dass ich etwas möchte, das mit den NIO -Networking -Bibliotheken gut spielen wird, anstatt zurück zu einem Thread pro Verbindungsmodell zurückzukehren, der zur Unterstützung eines blockierenden InputStreams erforderlich ist.

War es hilfreich?

Lösung

Dies ist eine (April 2009) Post aus der Xerces J-User Mailing-Liste, in der das ursprüngliche Poster genau das gleiche Problem aufweist. Eine potenziell sehr gute Antwort von "Jeff" wird gegeben, aber es gibt keine Follow -up der Reaktion des ursprünglichen Plakats:

http://www.nabble.com/parsing-an-xml-document-chunk-by-chunk-td22945319.html

Es ist potenziell neu genug, um auf der Liste zu stoßen oder zumindest bei der Suche zu helfen.

Bearbeiten

Fand einen weiteren nützlichen Link, erwähnte eine Bibliothek namens Woodstox und beschreibt den Zustand von Stream vs. Nio -basierten Parern und einige mögliche Ansätze zur Emulation eines Baches:

http://markmail.org/message/ogqqcj7dt3lwkBov

Andere Tipps

Überraschenderweise erwähnte niemand einen Java XML-Parser, der nicht blockierende ("Async") Parsen implementiert: Aalto. Ein Teil des Grundes kann der Mangel an Dokumentation (und seinem geringen Aktivitätsniveau) sein. Aalto implementiert die grundlegende STAX -API, aber auch kleinere Erweiterungen, um die Eingabe von Pushs zu ermöglichen (dieser Teil wurde nicht fertiggestellt; Funktionalität existiert, aber die API ist nicht abgeschlossen). Für weitere Informationen können Sie sich im Zusammenhang mit dem verwandten Auschecken ansehen Diskussionsgruppe.

EDIT: Jetzt sehe ich. Sie erhalten das XML in Stücken und möchten sie in einen ordnungsgemäßen XML -Parser versetzen. Sie brauchen also ein Objekt, das am einen Ende eine Warteschlange ist und am anderen Ende ein Eingabestream?

Sie können die in einen BytearrayoutputStream empfangenen Byte -Arrays aggregieren, sie in BytearrayInputStream konvertieren und dem SAXParser füttern.

Oder Sie können sich das PipeDInputStream/PipeDoutputStream -Paar ansehen. In diesem Fall müssen Sie das Parsen in einem anderen Thread durchführen, da SAX -Parser den aktuellen Thread verwendet, um Ereignisse zu emittieren und Ihren Empfang () zu blockieren.

Bearbeiten: Basierend auf den Kommentaren schlage ich vor, die Aggregationsroute zu nehmen. Sie sammeln die Stücke in einen BytearrayoutputStream. Um zu wissen, ob Sie alle Brocken für Ihr XML erhalten haben, überprüfen Sie, ob der aktuelle Stück oder der Inhalt des BytearrayoutputStream Ihr Endetikett des XML -Root -Knotens enthält. Dann können Sie die Daten einfach in einen Saxparser übergeben, der jetzt ohne Probleme im aktuellen Thread ausgeführt werden kann. Um eine unnötige Array-Nachschaffung zu vermeiden, können Sie Ihren eigenen unsynchronisierten einfachen Byte-Array-Wrapper implementieren oder nach einer solchen Implementierung suchen.

Prüfen OpenFire's XmlLELEIGHTWEIGHTPARSERS und wie es aufgrund von NIO XML -Nachrichten aus einzelnen Stücken generiert. Das gesamte Projekt ist eine großartige Quelle für Antworten zu NIO- und XMPP -Fragen.

Das Hinzufügen einer weiteren Antwort, da diese Frage für relevante Google -Suchanfragen hoch bleibt - Aalto-xml 0.9.7 (März 2011) hat ein asynchrones XML -Karten. Auf diese Weise können Sie willkürliche Stücke eines Dokuments bestehen, um die Parsen weiter zu analysieren, und einen neuen Staax -Event -Typ EVENT_INCOMPLETE Um anzuzeigen, ist der Eingangspuffer erschöpft und das Dokument bleibt unvollständig.

Das ist Tatu Salorant's (das Autor) Beispiel:

     byte[] msg = "<html>Very <b>simple</b> input document!</html>".getBytes();
      AsyncXMLStreamReader asyncReader = new InputFactoryImpl().createAsyncXMLStreamReader();
      final AsyncInputFeeder feeder = asyncReader.getInputFeeder();
      int inputPtr = 0; // as we feed byte at a time
      int type = 0;

      do {
        // May need to feed multiple "segments"
        while ((type = asyncReader.next()) == AsyncXMLStreamReader.EVENT_INCOMPLETE) {
          feeder.feedInput(msg, inputPtr++, 1);
          if (inputPtr >= msg.length) { // to indicate end-of-content (important for error handling)
            feeder.endOfInput();
          }
        }
        // and once we have full event, we just dump out event type (for now)
        System.out.println("Got event of type: "+type);
        // could also just copy event as is, using Stax, or do any other normal non-blocking handling:
        // xmlStreamWriter.copyEventFromReader(asyncReader, false);
      } while (type != AsyncXMLStreamReader.END_DOCUMENT);

Niosax arbeitet mit ByteBuffern

http://blog.retep.org/2010/06/25/niosax-sax-style-xml-parser-for-java-nio/

Der Quellcode für die neueste Version, die ich finden kann (10.6 aus 2010), befindet sich im Sonatype Maven -Repository:

https://oss.sonatype.org/content/repositories/releases/uk/org/retep/

Es tut mir leid, ich habe es nicht geschafft, dieses Problem zu lösen. Ich konnte keinen Parser wie den, den ich brauche. Aber ich denke, selbst selbst zu schreiben. Eine sehr einfache: Genauso wie Fallenbarkeitsstudium, aber genug, um mein Problem zu lösen, und hoffentlich Ihr Problem. Unortunatelly Ich war sehr geplant und in den nächsten zwei Wochen werde ich draußen sein, aber vielleicht im Juli fange ich an, daran zu arbeiten. Ich werde Sie wissen lassen, sobald ich etwas funktioniert.

mt

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top