JavaでXMLをHTMLに変換する

1. 前書き

このチュートリアルでは、一般的なJavaライブラリとテンプレートエンジン(JAXP、StAX、Freemarker、Mustache *)を使用してXMLをHTMLに変換する方法を説明します。

*2. 非整列化するXML *

HTMLに変換する前に、適切なJava表現に非整列化する単純なXMLドキュメントから始めましょう。 いくつかの重要な目標に留意してください。
  1. すべてのサンプルで同じXMLを保持する

  2. で構文的および意味的に有効なHTML5ドキュメントを作成します
    end

  3. すべてのXML要素をテキストに変換します

    サンプルのXMLとして単純なJenkins通知を使用してみましょう。
<?xml version="1.0" encoding="UTF-8"?>
<notification>
    <from>[email protected]</from>
    <heading>Build #7 passed</heading>
    <content>Success: The Jenkins CI build passed</content>
</notification>
そして、それは非常に簡単です。 ルート要素といくつかのネストされた要素が含まれます。
HTMLファイルを作成するときに、一意のXMLタグをすべて削除し、キーと値のペアを出力することを目指します。

*3. JAXP *

XML処理用のJavaアーキテクチャ(https://docs.oracle.com/javase/8/docs/technotes/guides/xml/jaxp/index.html[JAXP])は、人気のある機能を拡張することを目的としたライブラリです。追加のDOMサポートを備えたSAXパーサー。 JAXPは、SAX Parserを使用して、POJOとの間でXML定義オブジェクトを*マーシャリングおよびアンマーシャリングする機能を提供します。 また、組み込みのDOMヘルパーも使用します。
https://search.maven.org/search?q=a:jaxp-api%20g:javax.xml[JAXPのMaven依存関係]をプロジェクトに追加しましょう。
<dependency>
    <groupId>javax.xml</groupId>
    <artifactId>jaxp-api</artifactId>
    <version>1.4.2</version>
</dependency>

* 3.1。 DOM Builderを使用したアンマーシャリング*

まず、XMLファイルをJava _Element_オブジェクトに非整列化します。
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);

Document input = factory
  .newDocumentBuilder()
  .parse(resourcePath);
Element xml = input.getDocumentElement();

* 3.2。 Map *でXMLファイルの内容を抽出する

それでは、XMLファイルの関連コンテンツを使用して_Map_を作成しましょう。
Map<String, String> 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。 DOM Builderを使用したマーシャリング*

XMLをHTMLファイルにマーシャリングすることは、もう少し複雑です。
HTMLを書き出すために使用する転送_Document_を準備しましょう。
Document doc = factory
  .newDocumentBuilder()
  .newDocument();
次に、_map_の_Document_に_Elements_を入力します。
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);
最後に、_TransformerFactory_ *を使用して_Document_オブジェクトを*マーシャリングしましょう:
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));
}
_output.toString()_を呼び出すと、HTML表現が取得されます。
*工場で設定した追加の機能と属性の一部は、https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html [XXEインジェクションを避けるためのOWASPプロジェクトの推奨事項] *から取得したことに注意してください。

*4. StAX *

使用できるもう1つのライブラリは、XML用のストリーミングAPI(link:/java-stax[StAX])です。 JAXPのように、StAXは2004年以来長い間存在しています。
他の2つのライブラリは、XMLファイルの解析を簡素化します。 これは単純なタスクやプロジェクトには適していますが、それほど重要ではありません*反復する必要がある場合、または要素の解析自体を明示的かつ詳細に制御する必要がある場合*。 そこでStAXが役立ちます。
https://search.maven.org/search?q=g:javax.xml.stream%20AND%20a:stax-api[StAX APIのMaven依存関係]をプロジェクトに追加しましょう。
<dependency>
    <groupId>javax.xml.stream</groupId>
    <artifactId>stax-api</artifactId>
    <version>1.0-2</version>
</dependency>

* 4.1。 StAX *を使用したアンマーシャリング

単純な反復制御フローを使用して、XML値を_Map_ *に*保存します。
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<String, String> 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。 StAX *を使用したマーシャリング

では、_map_を使用して* HTMLを書きましょう*:
try (Writer output = new StringWriter()) {
    XMLStreamWriter writer = XMLOutputFactory
      .newInstance()
      .createXMLStreamWriter(output);

    writer.writeDTD("<!DOCTYPE html>");
    writer.writeStartElement("html");
    writer.writeAttribute("lang", "en");
    writer.writeStartElement("head");
    writer.writeDTD("<META http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">");
    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();
}
JAXPの例のように、_output.toString()_を呼び出してHTML表現を取得できます。

5. テンプレートエンジンの使用

HTML表現を作成する代わりに、https://www.baeldung.com/spring-template-engines [テンプレートエンジン]を使用できます。 Javaエコシステムには複数のオプションがあります。 それらのいくつかを探検しましょう。

* 5.1。 Apache Freemarker *を使用する

link:/freemarker-in-spring-mvc-tutorial[Apache FreeMarker]は、テキスト出力(HTML Webページ、電子メール、構成ファイル、ソースコードなど)を生成するためのJavaベースのテンプレートエンジンです。 。)テンプレートおよび変更データに基づきます。
それを使用するために、https://search.maven.org/search?q = g:org.freemarker%20AND%20a:freemarker [freemarker]依存関係をhttps:// wwwに追加する必要があります。 baeldung.com/maven[Maven] project:
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.29</version>
</dependency>
まず、FreeMarker構文を使用してテンプレートを作成しましょう。
<!DOCTYPE html>
<html lang="en">
<head>
    <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>${heading}</title>
</head>
<body>
<p>${from}</p>
<p>${content}</p>
</body>
</html>
では、_map_を再利用して、テンプレートのギャップを埋めましょう。
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。 Moustache *を使用する

Moustacheは、ロジックのないテンプレートエンジンです。 Moustacheは、HTML、設定ファイル、ソースコードなど、ほとんどすべてに使用できます。 ハッシュまたはオブジェクトで提供される値を使用して、テンプレート内のタグを展開することにより機能します。
これを使用するには、https://search.maven.org/search?q = g:com.github.spullara.mustache.java%20AND%20a:compiler [mustache]依存関係をhttpsに追加する必要があります。 //www.baeldung.com/maven[Maven]プロジェクト:
<dependency>
    <groupId>com.github.spullara.mustache.java</groupId>
    <artifactId>compiler</artifactId>
    <version>0.9.6</version>
</dependency>
Moustache構文を使用してテンプレートの作成を始めましょう。
<!DOCTYPE html>
<html lang="en">
<head>
    <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>{{heading}}</title>
</head>
<body>
<p>{{from}}</p>
<p>{{content}}</p>
</body>
</html>
それでは、テンプレートに_map_を入力しましょう:
MustacheFactory mf = new DefaultMustacheFactory();
Mustache mustache = mf.compile(templateFile);
try (Writer output = new StringWriter()) {
    mustache.execute(output, staxTransformer.getMap());
    output.flush();
}

*6. 結果のHTML *

最後に、すべてのコードサンプルを使用して、同じHTML出力を取得します。
<!DOCTYPE html>
<html lang="en">
<head>
    <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Build #7 passed</title>
</head>
<body>
<p>from: [email protected]</p>
<p>Success: The Jenkins CI build passed</p>
</body>
</html>

7. 結論

このチュートリアルでは、JAXP、StAX、Freemarker、Mustacheを使用してXMLをHTMLに変換する基本を学びました。
JavaでのXMLの詳細については、ここBaeldungにある他の優れたリソースをご覧ください。
  • link:/xstream-deserialize-xml-to-object [デシリアライズ
    XStreamのオブジェクトへのXML]

  • Serializing
    XStreamのXMLへのオブジェクト

  • link://www.baeldung.com/java-xml-libraries [Java XML Libraries]

    いつものように、ここで見られる完全なコードサンプルはhttps://github.com/eugenp/tutorials/tree/master/xml[over on GitHub]で入手できます。