DOM-Analyse mit Xerces

Arbeiten mit XML-Dateien in Java mithilfe der DOM-Analyse

1. Überblick

In diesem Tutorial wird erläutert, wie DOM mitApache Xerces analysiert wird - einer ausgereiften und etablierten Bibliothek zum Parsen / Bearbeiten von XML.

Es gibt mehrere Optionen zum Parsen eines XML-Dokuments. In diesem Artikel konzentrieren wir uns auf das Parsen von DOM. Der DOM-Parser lädt ein Dokument und erstellt einen gesamten hierarchischen Baum im Speicher.

Eine Übersicht über die Unterstützung von XML-Bibliotheken in Java finden Sie in unseren vorherigenarticle.

2. Unser Dokument

Beginnen wir mit dem XML-Dokument, das wir in unserem Beispiel verwenden werden:



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

Beachten Sie, dass unser Dokument einen Stammknoten namens "Tutorials" mit 4 untergeordneten "Tutorials" enthält. Jedes davon hat zwei Attribute: "tutId" und "type". Außerdem hat jedes "Tutorial" 4 untergeordnete Knoten: "Titel", "Beschreibung", "Datum" und "Autor".

Jetzt können wir mit dem Parsen dieses Dokuments fortfahren.

3. Laden der XML-Datei

Zunächst sollten wir beachten, dassthe Apache Xerces library is packaged with the JDK ist, sodass wir kein zusätzliches Setup benötigen.

Lassen Sie uns gleich mit dem Laden unserer XML-Datei beginnen:

DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(new File("src/test/resources/example_jdom.xml"));
doc.getDocumentElement().normalize();

Im obigen Beispiel erhalten wir zuerst eine Instanz der KlasseDocumentBuilder und verwenden dann die Methodeparse() im XML-Dokument, um ein Objekt vonDocumentabzurufen, das sie darstellt.

Wir müssen auch dienormalize()-Methode verwenden, um sicherzustellen, dass die Dokumenthierarchie nicht durch zusätzliche Leerzeichen oder neue Zeilen innerhalb von Knoten beeinflusst wird.

4. Analysieren des DOM

Lassen Sie uns nun unsere XML-Datei untersuchen.

Beginnen wir mit dem Abrufen aller Elemente mit dem Tag "Tutorial". Wir können dies mit der MethodegetElementsByTagName() tun, dieNodeList: zurückgibt

@Test
public void whenGetElementByTag_thenSuccess() {
    NodeList nodeList = doc.getElementsByTagName("tutorial");
    Node first = nodeList.item(0);

    assertEquals(4, nodeList.getLength());
    assertEquals(Node.ELEMENT_NODE, first.getNodeType());
    assertEquals("tutorial", first.getNodeName());
}

Es ist wichtig zu beachten, dassNode is the primary datatype for the DOM components. Alle Elemente, Attribute und Texte gelten als Knoten.

Als nächstes wollen wir sehen, wie wir die Attribute des ersten Elements mitgetAttributes() erhalten können:

@Test
public void whenGetFirstElementAttributes_thenSuccess() {
    Node first = doc.getElementsByTagName("tutorial").item(0);
    NamedNodeMap attrList = first.getAttributes();

    assertEquals(2, attrList.getLength());

    assertEquals("tutId", attrList.item(0).getNodeName());
    assertEquals("01", attrList.item(0).getNodeValue());

    assertEquals("type", attrList.item(1).getNodeName());
    assertEquals("java", attrList.item(1).getNodeValue());
}

Hier erhalten wir dasNamedNodeMap-Objekt und verwenden dann dieitem(index)-Methode, um jeden Knoten abzurufen.

Für jeden Knoten können wirgetNodeName() undgetNodeValue() verwenden, um ihre Attribute zu finden.

5. Durchqueren von Knoten

Als nächstes sehen wir uns an, wie DOM-Knoten durchlaufen werden.

Im folgenden Test werden die untergeordneten Knoten des ersten Elements durchlaufen und deren Inhalt gedruckt:

@Test
public void whenTraverseChildNodes_thenSuccess() {
    Node first = doc.getElementsByTagName("tutorial").item(0);
    NodeList nodeList = first.getChildNodes();
    int n = nodeList.getLength();
    Node current;
    for (int i=0; i

Zuerst erhalten wir dieNodeList mit dergetChildNodes()-Methode, durchlaufen sie dann und drucken den Knotennamen und den Textinhalt.

Die Ausgabe zeigt den Inhalt des ersten "Tutorial" -Elements in unserem Dokument:

title: Guava
description: Introduction to Guava
date: 04/04/2016
author: GuavaAuthor

6. Ändern des DOM

Wir können auch Änderungen am DOM vornehmen.

Als Beispiel ändern wir den Wert des Attributstypevon "java" in "other":

@Test
public void whenModifyDocument_thenModified() {
    NodeList nodeList = doc.getElementsByTagName("tutorial");
    Element first = (Element) nodeList.item(0);

    assertEquals("java", first.getAttribute("type"));

    first.setAttribute("type", "other");
    assertEquals("other", first.getAttribute("type"));
}

Hier ist das Ändern des Attributwerts eine einfache Sache des Aufrufs derElementsetAttribute()-Methode.

7. Neues Dokument erstellen

Neben der Änderung des DOM können wir auch neue XML-Dokumente von Grund auf neu erstellen.

Schauen wir uns zunächst die Datei an, die wir erstellen möchten:



    
        [email protected]
    

Unser XML enthält einenusers-Stammknoten mit einemuser-Element, das auch einen untergeordneten Knotenemail. hat

Um dies zu erreichen, müssen wir zuerst dienewDocument()-Methode vonBuilderaufrufen, die einDocument-Objekt zurückgibt.

Dann rufen wir diecreateElement()-Methode des neuen Objekts auf:

@Test
public void whenCreateNewDocument_thenCreated() throws Exception {
    Document newDoc = builder.newDocument();
    Element root = newDoc.createElement("users");
    newDoc.appendChild(root);

    Element first = newDoc.createElement("user");
    root.appendChild(first);
    first.setAttribute("id", "1");

    Element email = newDoc.createElement("email");
    email.appendChild(newDoc.createTextNode("[email protected]"));
    first.appendChild(email);

    assertEquals(1, newDoc.getChildNodes().getLength());
    assertEquals("users", newDoc.getChildNodes().item(0).getNodeName());
}

Um jedes Element zum DOM hinzuzufügen, rufen wir auch die MethodeappendChild()auf.

8. Dokument speichern

Nachdem Sie unser Dokument geändert oder von Grund auf neu erstellt haben, müssen Sie es in einer Datei speichern.

Wir beginnen mit dem Erstellen einesDOMSource-Objekts und verwenden dann ein einfachesTransformer, um das Dokument in einer Datei zu speichern:

private void saveDomToFile(Document document,String fileName)
  throws Exception {

    DOMSource dom = new DOMSource(document);
    Transformer transformer = TransformerFactory.newInstance()
      .newTransformer();

    StreamResult result = new StreamResult(new File(fileName));
    transformer.transform(dom, result);
}

Ebenso können wir unser Dokument in der Konsole drucken:

private void printDom(Document document) throws Exception{
    DOMSource dom = new DOMSource(document);
    Transformer transformer = TransformerFactory.newInstance()
        .newTransformer();

    transformer.transform(dom, new StreamResult(System.out));
}

9. Fazit

In diesem kurzen Artikel haben wir gelernt, wie Sie mit dem Xerces DOM-Parser ein XML-Dokument erstellen, ändern und speichern.

Wie immer ist der vollständige Quellcode für die Beispieleover on GitHub verfügbar.