Konvertieren Sie XML in HTML in HTML

1. Einleitung

In diesem Tutorial wird beschrieben, wie XML mithilfe gängiger Java-Bibliotheken und Template-Engines - JAXP, StAX, Freemarker und Moustache - in HTML konvertiert wird .

2. Ein XML zum Unmarshal

Beginnen wir mit einem einfachen XML-Dokument, das wir in eine geeignete Java-Darstellung aufheben, bevor wir es in HTML konvertieren. Wir werden einige wichtige Ziele berücksichtigen:

  1. Behalten Sie für alle unsere Beispiele das gleiche XML bei
  2. Erstellen Sie am Ende ein syntaktisch und semantisch gültiges HTML5-Dokument
  3. Konvertieren Sie alle XML-Elemente in Text

Verwenden wir eine einfache Jenkins-Benachrichtigung als XML-Beispiel:

  [email protected] Build #7 passed Success: The Jenkins CI build passed 

Und es ist ziemlich einfach. Es enthält ein Stammelement und einige verschachtelte Elemente.

Wir werden versuchen, alle eindeutigen XML-Tags zu entfernen und Schlüssel-Wert-Paare auszudrucken, wenn wir unsere HTML-Datei erstellen.

3. JAXP

Java Architecture for XML Processing (JAXP) ist eine Bibliothek, die die Funktionalität des beliebten SAX Parser mit zusätzlicher DOM-Unterstützung erweitern sollte. JAXP bietet die Möglichkeit, XML-definierte Objekte mithilfe von SAX Parser in und aus POJOs zu marshallen und zu marshallen . Wir werden auch die eingebauten DOM-Helfer verwenden.

Fügen wir unserem Projekt die Maven-Abhängigkeit für JAXP hinzu:

 javax.xml jaxp-api 1.4.2  

3.1. Unmarshalling mit DOM Builder

Beginnen wir damit, unsere XML-Datei zunächst in ein Java Element- Objekt zu entfernen :

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); factory.setFeature("//apache.org/xml/features/disallow-doctype-decl", true); Document input = factory .newDocumentBuilder() .parse(resourcePath); Element xml = input.getDocumentElement(); 

3.2. Extrahieren des Inhalts der XML-Datei in einer Karte

Erstellen wir nun eine Karte mit den relevanten Inhalten unserer XML-Datei:

Map map = new HashMap(); map.put("heading", xml.getElementsByTagName("heading") .item(0) .getTextContent()); map.put("from", String.format("from: %s", xml.getElementsByTagName("from") .item(0) .getTextContent())); map.put("content", xml.getElementsByTagName("content") .item(0) .getTextContent());

3.3. Marshalling mit DOM Builder

Das Marshalling unseres XML in eine HTML-Datei ist etwas komplizierter.

Lassen Sie uns einen Transfer vorbereiten Dokument , dass wir die HTML zu schreiben , verwenden werden:

Document doc = factory .newDocumentBuilder() .newDocument(); 

Als nächstes füllen wir das Dokument mit den Elementen in unserer Karte :

Element html = doc.createElement("html"); Element head = doc.createElement("head"); html.setAttribute("lang", "en"); Element title = doc.createElement("title"); title.setTextContent(map.get("heading")); head.appendChild(title); html.appendChild(head); Element body = doc.createElement("body"); Element from = doc.createElement("p"); from.setTextContent(map.get("from")); Element success = doc.createElement("p"); success.setTextContent(map.get("content")); body.appendChild(from); body.appendChild(success); html.appendChild(body); doc.appendChild(html); 

Lassen Sie uns abschließend unser Document- Objekt mit einer TransformerFactory zusammenstellen :

TransformerFactory transformerFactory = TransformerFactory.newInstance(); transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); try (Writer output = new StringWriter()) { Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(doc), new StreamResult(output)); }

Wenn wir output.toString () aufrufen , erhalten wir die HTML-Darstellung.

Beachten Sie, dass einige der zusätzlichen Funktionen und Attribute, die wir in unserer Fabrik festgelegt haben, den Empfehlungen des OWASP-Projekts entnommen wurden, um eine XXE-Injektion zu vermeiden .

4. STAX

Eine weitere Bibliothek, die wir verwenden können, ist die Streaming-API für XML (StAX). StAX gibt es wie JAXP schon lange - seit 2004.

Die beiden anderen Bibliotheken vereinfachen das Parsen von XML-Dateien. Das ist großartig für einfache Aufgaben oder Projekte, aber weniger, wenn wir iterieren müssen oder eine explizite und fein abgestimmte Kontrolle über das Parsen von Elementen selbst haben müssen . Hier bietet sich StAX an.

Fügen wir unserem Projekt die Maven-Abhängigkeit für die StAX-API hinzu:

 javax.xml.stream stax-api 1.0-2  

4.1. Unmarshalling mit StAX

Wir werden einen einfachen Iterationssteuerungsfluss verwenden, um XML-Werte in unserer Map zu speichern :

XMLInputFactory factory = XMLInputFactory.newInstance(); factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); factory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE); XMLStreamReader input = null; try (FileInputStream file = new FileInputStream(resourcePath)) { input = factory.createXMLStreamReader(file); Map map = new HashMap(); while (input.hasNext()) { input.next(); if (input.isStartElement()) { if (input.getLocalName().equals("heading")) { map.put("heading", input.getElementText()); } if (input.getLocalName().equals("from")) { map.put("from", String.format("from: %s", input.getElementText())); } if (input.getLocalName().equals("content")) { map.put("content", input.getElementText()); } } } } finally { if (input != null) { input.close(); } }

4.2. Marshalling mit StAX

Verwenden wir nun unsere Karte und schreiben den HTML-Code aus :

try (Writer output = new StringWriter()) { XMLStreamWriter writer = XMLOutputFactory .newInstance() .createXMLStreamWriter(output); writer.writeDTD(""); writer.writeStartElement("html"); writer.writeAttribute("lang", "en"); writer.writeStartElement("head"); writer.writeDTD(""); writer.writeStartElement("title"); writer.writeCharacters(map.get("heading")); writer.writeEndElement(); writer.writeEndElement(); writer.writeStartElement("body"); writer.writeStartElement("p"); writer.writeCharacters(map.get("from")); writer.writeEndElement(); writer.writeStartElement("p"); writer.writeCharacters(map.get("content")); writer.writeEndElement(); writer.writeEndElement(); writer.writeEndDocument(); writer.flush(); }

Wie im JAXP-Beispiel können wir output.toString () aufrufen , um die HTML-Darstellung abzurufen .

5. Verwenden von Vorlagen-Engines

Als Alternative zum Schreiben der HTML-Darstellung können wir Template-Engines verwenden. Es gibt mehrere Optionen im Java-Ökosystem. Lassen Sie uns einige von ihnen erkunden.

5.1. Verwenden von Apache Freemarker

Apache FreeMarker ist eine Java-basierte Vorlagen-Engine zum Generieren von Textausgaben (HTML-Webseiten, E-Mails, Konfigurationsdateien, Quellcode usw.) basierend auf Vorlagen und dem Ändern von Daten.

Um es verwenden zu können, müssen wir unserem Maven-Projekt die Freemarker-Abhängigkeit hinzufügen:

 org.freemarker freemarker 2.3.29 

Lassen Sie uns zunächst eine Vorlage mit der FreeMarker-Syntax erstellen:

    ${heading}   

${from}

${content}

Lassen Sie uns nun unsere Karte wiederverwenden und die Lücken in der Vorlage füllen:

Configuration cfg = new Configuration(Configuration.VERSION_2_3_29); cfg.setDirectoryForTemplateLoading(new File(templateDirectory)); cfg.setDefaultEncoding(StandardCharsets.UTF_8.toString()); cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); cfg.setLogTemplateExceptions(false); cfg.setWrapUncheckedExceptions(true); cfg.setFallbackOnNullLoopVariable(false); Template temp = cfg.getTemplate(templateFile); try (Writer output = new StringWriter()) { temp.process(staxTransformer.getMap(), output); }

5.2. Schnurrbart benutzen

Mustache is a logic-less template engine. Mustache can be used for HTML, config files, source code — pretty much anything. It works by expanding tags in a template using values provided in a hash or object.

To use it, we'll need to add the mustache dependency to our Maven project:

 com.github.spullara.mustache.java compiler 0.9.6 

Let's start creating a template using the Mustache syntax:

    {{heading}}   

{{from}}

{{content}}

Now, let's fill the template with our map:

MustacheFactory mf = new DefaultMustacheFactory(); Mustache mustache = mf.compile(templateFile); try (Writer output = new StringWriter()) { mustache.execute(output, staxTransformer.getMap()); output.flush(); }

6. The Resulting HTML

In the end, with all our code samples, we'll get the same HTML output:

    Build #7 passed   

from: [email protected]

Success: The Jenkins CI build passed

7. Conclusion

In this tutorial, we've learned the basics of using JAXP, StAX, Freemarker, and Mustache to convert XML into HTML.

For more information about XML in Java, check out these other great resources right here on Baeldung:

  • Deserializing XML to Objects in XStream
  • Serializing Objects to XML in XStream
  • Java XML Libraries

Wie immer sind die vollständigen Codebeispiele hier auf GitHub verfügbar.