Unterstützung für XML-Bibliotheken in Java

Unterstützung für XML-Bibliotheken in Java

1. Einführung

In diesem Artikel werden Java XML-Bibliotheken und APIs verglichen.

Dies ist der zweite Artikel aus der Reihe über die Java-Unterstützung für XML. Wenn Sie tiefer in die XPath-Unterstützung in Java einsteigen möchten, schauen Sie sichthe previous article an.

2. Überblick

Jetzt werden wir uns eingehender mit der Unterstützung der XML-Welt befassen und zunächst alle fachbezogenen Initialen so einfach wie möglich erklären.

In der Java XML-Unterstützung gibt es nur wenige API-Definitionen, von denen jede Vor- und Nachteile hat.

  • SAX: Es handelt sich um eine ereignisbasierte Parsing-API, die einen Zugriff auf niedriger Ebene bietet, speichereffizient und schneller als DOM ist, da nicht der gesamte Dokumentbaum in den Speicher geladen wird, jedoch keine Navigation unterstützt wird die von XPath bereitgestellte, obwohl sie effizienter ist, ist sie auch schwieriger zu verwenden.

  • DOM: Es ist ein modellbasierter Parser, der ein Baumstrukturdokument in den Speicher lädt, sodass wir die ursprüngliche Elementreihenfolge haben. Wir können in unserem Dokument in beide Richtungen navigieren. Es bietet eine API zum Lesen und Schreiben. Es bietet XML-Manipulation und Es ist sehr einfach zu bedienen, obwohl der Preis die Speicherressourcen stark belastet.

  • StAX: Es bietet die Einfachheit von DOM und die Effizienz von SAX, aber es fehlen einige von DOM bereitgestellte Funktionen wie die XML-Manipulation, und es ermöglicht uns nur, das Dokument vorwärts zu navigieren.

  • JAXB: Es ermöglicht uns, durch das Dokument in beide Richtungen zu navigieren, ist effizienter als DOM, ermöglicht die Konvertierung von XML in Java-Typen und unterstützt die XML-Manipulation, kann jedoch nur ein gültiges XML-Dokument analysieren.

Sie können immer noch einige Verweise auf JAXP finden, aber die letzte Veröffentlichung dieses Projekts ist im März 2013 und es ist praktisch tot.

XML Apis Table

XML-APIs-Tabelle

3. Das XML

In diesem Abschnitt werden die beliebtesten Implementierungen vorgestellt, damit wir reale Arbeitsproben testen und Unterschiede zwischen ihnen überprüfen können.

In den folgenden Beispielen arbeiten wir mit einer einfachen XML-Datei mit einer Struktur wie dieser:


    
        Guava
        Introduction to Guava
        04/04/2016
        GuavaAuthor
    
    ...

4. DOM4J

Wir werden uns zunächst ansehen, was wir mitDOM4J tun können. In diesem Beispiel müssen wir die letzte Version dieserdependency hinzufügen.

Dies ist eine der beliebtesten Bibliotheken für die Arbeit mitXML-Dateien, da wir damit bidirektional lesen, neue Dokumente erstellen und vorhandene aktualisieren können.

DOM4J kann mitDOM,SAX,XPath undXLST arbeiten. SAX wird überJAXP unterstützt. __

Schauen wir uns hier zum Beispiel an, wie wir eine Elementfilterung nach einer bestimmten ID auswählen können.

SAXReader reader = new SAXReader();
Document document = reader.read(file);
List elements = document.selectNodes("//*[@tutId='" + id + "']");
return elements.get(0);

Die KlasseSAXReader ist für die Erstellung einesDOM4J-Baums aus den Analyseereignissen vonSAXverantwortlich. Sobald wir einorg.dom4j.Document haben, müssen wir nur die notwendige Methode aufrufen und denXPath-Ausdruck alsString. an ihn übergeben

Wir können ein vorhandenes Dokument laden, Änderungen am Inhalt vornehmen und dann die Originaldatei aktualisieren.

for (Node node : nodes) {
    Element element = (Element)node;
    Iterator iterator = element.elementIterator("title");
    while (iterator.hasNext()) {
        Element title =(Element)iterator.next();
        title.setText(title.getText() + " updated");
    }
}
XMLWriter writer = new XMLWriter(
  new FileWriter(new File("src/test/resources/example_updated.xml")));
writer.write(document);
writer.close();

Im obigen Beispiel ändern wir den Inhalt jedes Titels und erstellen eine neue Datei.

Beachten Sie hier, wie einfach es ist, dienode jedes Titels in einer Liste abzurufen, indem SieelementIterator aufrufen und den Namen dernode. übergeben

Sobald wir unseren Inhalt geändert haben, verwenden wir dieXMLWriter, die einenDOM4J-Baum nehmen und ihn alsXML in einen Stream formatieren.

Das Erstellen eines neuen Dokuments von Grund auf ist so einfach wie unten dargestellt.

Document document = DocumentHelper.createDocument();
Element root = document.addElement("XMLTutorials");
Element tutorialElement = root.addElement("tutorial").addAttribute("tutId", "01");
tutorialElement.addAttribute("type", "xml");
tutorialElement.addElement("title").addText("XML with Dom4J");
...
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(
  new FileWriter(new File("src/test/resources/example_new.xml")), format);
writer.write(document);
writer.close();

DocumentHelper gibt uns eine Sammlung von Methoden, die vonDOM4J verwendet werden können, z. B.createDocument, die ein leeres Dokument erstellen, um damit zu arbeiten.

Mit den vonDOM4J bereitgestellten Methoden können wir so viele Attribute oder Elemente erstellen, wie wir benötigen. Sobald wir unser Dokument fertiggestellt haben, schreiben wir es einfach in eine Datei, wie wir es zuvor mit dem Aktualisierungsfall getan haben.

5. JDOM

Um mitJDOM, arbeiten zu können, müssen wir diesedependency zu unserem Pom hinzufügen.

Der Arbeitsstil vonJDOM’sist dem vonDOM4J’sziemlich ähnlich, daher werden wir uns nur einige Beispiele ansehen:

SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(this.getFile());
Element tutorials = doc.getRootElement();
List titles = tutorials.getChildren("tutorial");

Im obigen Beispiel rufen wir alle Elemente auf sehr einfache Weise aus dem Stammelement ab, wie wir es mitDOM4J: tun können

SAXBuilder builder = new SAXBuilder();
Document document = (Document) builder.build(file);
String filter = "//*[@tutId='" + id + "']";
XPathFactory xFactory = XPathFactory.instance();
XPathExpression expr = xFactory.compile(filter, Filters.element());
List node = expr.evaluate(document);

Auch hier im obigen Code haben wir eineSAXBuilder, die eineDocument Instanz aus einer bestimmten Datei erstellt. Wir rufen ein Element anhand seines AttributstutId ab, indem wir einen AusdruckXPathanXPathFactory übergeben, der vonJDOM2. bereitgestellt wird

6. StAX

Nun werden wir sehen, wie wir alle Elemente mitStax API aus unserem Stammelement abrufen können. Stax ist seit Java 6 inJDK enthalten, sodass Sie keine Abhängigkeiten hinzufügen müssen.

Zunächst müssen wir eineTutorial-Klasse erstellen:

public class Tutorial {
    private String tutId;
    private String type;
    private String title;
    private String description;
    private String date;
    private String author;

    // standard getters and setters
}

und dann sind wir bereit zu folgen mit:

List tutorials = new ArrayList<>();
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLEventReader eventReader = factory.createXMLEventReader(new FileReader(this.getFile()));
Tutorial current;
while (eventReader.hasNext()) {
    XMLEvent event = eventReader.nextEvent();
    switch (event.getEventType()) {
        case XMLStreamConstants.START_ELEMENT:
            StartElement startElement = event.asStartElement();
            String qName = startElement.getName().getLocalPart();
            ...
            break;
        case XMLStreamConstants.CHARACTERS:
            Characters characters = event.asCharacters();
            ...
            break;
        case XMLStreamConstants.END_ELEMENT:
            EndElement endElement = event.asEndElement();

            // check if we found the closing element
            // close resources that need to be explicitly closed
            break;
    }
}

Im obigen Beispiel mussten wir eine Klasse erstellen, in der die abgerufenen Daten gespeichert werden, damit wir die Informationen abrufen können.

Um das Dokument zu lesen, haben wir so genannte Event-Handler deklariert und sie zum Navigieren in unserem Dokument verwendet. Denken Sie daran, dass die SAX-Implementierungen keine bidirektionale Navigation bieten. Wie Sie hier sehen, ist viel Arbeit erforderlich, um eine einfache Liste von Elementen abzurufen.

7. JAXB

JAXB ist inJDK enthalten, ebenso wie Xerces, für die keine zusätzliche Abhängigkeit erforderlich ist.

Es ist sehr einfach, Informationen aus einerXML-Datei mitJAXB zu laden, zu erstellen und zu bearbeiten.

Wir müssen nur die richtigen Java-Entitäten erstellen, um dieXMLzu binden, und das war's.

JAXBContext jaxbContext = JAXBContext.newInstance(Tutorials.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Tutorials tutorials = (Tutorials) jaxbUnmarshaller.unmarshal(this.getFile());

Im obigen Beispiel laden wir unsereXML-Datei in unser Objekt und können von dort aus alles als normale Java-Struktur behandeln.

Das Erstellen eines neuen Dokuments ist so einfach wie das Lesen, jedoch in umgekehrter Reihenfolge, wie im folgenden Code beschrieben.

Zunächst ändern wir die KlasseTutorial, umJAXB Anmerkungen zugetters undsetters hinzuzufügen:

public class Tutorial {
    ...

    public String getTutId() {
        return tutId;
    }

    @XmlAttribute
    public void setTutId(String tutId) {
        this.tutId = tutId;
    }
    ...
    @XmlElement
    public void setTitle(String title) {
        this.title = title;
    }
    ...
}

@XmlRootElement
public class Tutorials {
    private List tutorial;

    // standard getters and setters with @XmlElement annotation
}

Mit@XmlRootElement definieren wir, welches Objekt den Stammknoten unseres Dokuments darstellen soll, und verwenden dann@XmlAttribute oder@XmlElement, um zu definieren, ob dieses Attribut ein Attribut eines Knotens oder ein Element von darstellt das Dokument.

Dann können wir folgen mit:

Tutorials tutorials = new Tutorials();
tutorials.setTutorial(new ArrayList<>());
Tutorial tut = new Tutorial();
tut.setTutId("01");
...
tutorials.getTutorial().add(tut);
JAXBContext jaxbContext = JAXBContext.newInstance(Tutorials.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(tutorials, file);

Wie Sie sehen, ist das Binden von XML-Dateien an Java-Objekte der einfachste Weg, um diese Art von Dateien zu bearbeiten.

8. XPath-Ausdrucksunterstützung

Um komplexe XPath-Ausdrücke zu erstellen, können wir Jaxen verwenden. Dies ist eine Open-Source-XPath-Bibliothek, die an viele verschiedene Objektmodelle angepasst werden kann, einschließlichDOM,XOM,DOM4J undJDOM.

Wir können XPath-Ausdrücke erstellen und sie mit vielen unterstützten Dokumenten kompilieren.

String expression = "/tutorials/tutorial";
XPath path = new DOMXPath(expression);
List result = path.selectNodes(xmlDocument);

Damit es funktioniert, müssen wir diesedependency zu unserem Projekt hinzufügen.

9. Fazit

Wie Sie sehen, gibt es viele Möglichkeiten, mitXML zu arbeiten. Abhängig von den Anforderungen Ihrer Anwendung können Sie mit jeder von ihnen arbeiten, oder Sie müssen möglicherweise zwischen Effizienz und Einfachheit wählen.

Die vollständigen Arbeitsbeispiele für diesen Artikel finden Sie in unserem Git-Repositoryhere.