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

1. Übersicht

In diesem Tutorial wird erläutert, wie DOM mit Apache 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 unserem vorherigen Artikel.

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 Knoten "Tutorial" hat. Jedes dieser Attribute 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, dass die Apache Xerces-Bibliothek mit dem JDK gepackt 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 DocumentBuilder- Klasse und verwenden dann die parse () -Methode für das XML-Dokument, um ein Document- Objekt abzurufen, das sie darstellt.

Wir müssen auch die normalize () -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 Methode getElementsByTagName () tun , die eine NodeList 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, dass der Knoten der primäre Datentyp für die DOM-Komponenten ist . Alle Elemente, Attribute und Texte werden als Knoten betrachtet.

Als nächstes wollen wir sehen, wie wir die Attribute des ersten Elements mit getAttributes () 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 das NamedNodeMap- Objekt und verwenden dann die item (index) -Methode, um jeden Knoten abzurufen.

Für jeden Knoten können wir getNodeName () und getNodeValue () verwenden , um ihre Attribute zu finden.

5. Knoten durchlaufen

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

Im folgenden Test durchlaufen wir die untergeordneten Knoten des ersten Elements und drucken deren Inhalt:

@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
    

First, we get the NodeList using the getChildNodes() method, then iterate through it, and print the node name and text content.

The output will show the contents of the first “tutorial” element in our document:

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

6. Modifying the DOM

We can also make changes to the DOM.

As an example, let's change the value of the type attribute from “java” to “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")); }

Here, changing the attribute value is a simple matter of calling an Element‘s setAttribute() method.

7. Creating a New Document

Besides modifying the DOM, we can also create new XML documents from scratch.

Let's first have a look at the file we want to create:

 [email protected] 

Our XML contains a users root node with one user element that also has a child node email.

To achieve this, we first have to call the Builder‘s newDocument() method which returns a Document object.

Then, we'll call the createElement() method of the new object:

@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()); }

To add each element to the DOM, we're also calling the appendChild() method.

8. Saving a Document

After modifying our document or creating one from scratch, we'll need to save it in a file.

We'll start with creating a DOMSource object, then use a simple Transformer to save the document in a file:

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); }

Similarly, we can print our document in the console:

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. Conclusion

In this quick article, we learned how to use the Xerces DOM parser to create, modify and save an XML document.

As always, the full source code for the examples is available over on GitHub.