Java : Transformer (XML) - API使用例

Transformer (Java SE 17 & JDK 17) の使用例まとめです。
だいたいのメソッドを網羅済みです。
API仕様のおともにどうぞ。


概要

このabstractクラスのインスタンスは、ソース・ツリーを結果ツリーに変換することができます。

クラス構成

Transformerクラスは以下の変換を行います。

  • XMLオブジェクト(DOMやSAX、StAX) → XML形式の文字列やファイル
  • DOM → SAX などのXMLオブジェクト間の変換
  • XSLT

DOMからXML形式の文字列へ変換する一連の流れは次のようになります。

final var builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
final var document = builder.newDocument();

final var root = document.createElement("root");
document.appendChild(root);

final var text = document.createTextNode("abcd");
root.appendChild(text);

final var factory = TransformerFactory.newInstance();
final var transformer = factory.newTransformer();

final var source = new DOMSource(document);
final var result = new StreamResult(new StringWriter());
transformer.transform(source, result);

//<?xml version="1.0" encoding="UTF-8" standalone="no"?><root>abcd</root>
System.out.println(result.getWriter());

関連記事:XML (DOM) の基本

コンストラクタ

Transformer ()

デフォルトのコンストラクタが意図的に保護されます。

protectedです。
独自にサブクラスを作ることは少ないと思いますので、コード例は割愛します。

メソッド

abstract void clearParameters ()

setParameterを使用して設定されたすべてのパラメータをクリアします。

final var xml = """
        <root/>
        """;

final var builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
final var document = builder.parse(new ByteArrayInputStream(xml.getBytes()));

final var xsl = """
        <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
          <xsl:output omit-xml-declaration="yes" />
          <xsl:param name="param">aaaa</xsl:param>

          <xsl:template match="root">
            <xsl:copy-of select="$param" />
          </xsl:template>

        </xsl:stylesheet>
        """;

final var factory = TransformerFactory.newInstance();
final var transformer = factory.newTransformer(
        new StreamSource(new ByteArrayInputStream(xsl.getBytes())));

System.out.println(transformer.getParameter("param")); // null
transformer.setParameter("param", "bbbb");

{
    System.out.println(transformer.getParameter("param")); // bbbb

    final var source = new DOMSource(document);
    final var result = new StreamResult(new StringWriter());
    transformer.transform(source, result);

    //bbbb
    System.out.println(result.getWriter());
}

transformer.clearParameters();

{
    System.out.println(transformer.getParameter("param")); // null

    final var source = new DOMSource(document);
    final var result = new StreamResult(new StringWriter());
    transformer.transform(source, result);

    //aaaa
    System.out.println(result.getWriter());
}

abstract ErrorListener getErrorListener ()

変換に有効なエラー・イベント・ハンドラを取得します。

// 意図的にエラーを起こすために、間違った構文のXMLを使います。
final var xml = """
        <root>
            <<<child>aaa</child>
        </root>
        """;

final var factory = TransformerFactory.newInstance();
final var transformer = factory.newTransformer();

final var listener = new ErrorListener() {
    @Override
    public void warning(TransformerException exception) {
        System.out.println("-- ErrorListener warning --");
        System.out.println(exception);
    }

    @Override
    public void error(TransformerException exception) {
        System.out.println("-- ErrorListener error --");
        System.out.println(exception);
    }

    @Override
    public void fatalError(TransformerException exception) {
        System.out.println("-- ErrorListener fatalError --");
        System.out.println(exception);
    }
};

transformer.setErrorListener(listener);
System.out.println(listener == transformer.getErrorListener()); // true

final var source = new StreamSource(new ByteArrayInputStream(xml.getBytes()));
final var result = new StreamResult(new StringWriter());

try {
    transformer.transform(source, result);
} catch (TransformerException e) {
    System.out.println("-- TransformerException --");
    System.out.println(e);
}

// 結果
// ↓
//-- ErrorListener error --
//javax.xml.transform.TransformerException:
// 要素のコンテンツは、整形式の文字データまたはマークアップで構成されている必要があります。
//-- TransformerException --
//javax.xml.transform.TransformerException:
// org.xml.sax.SAXParseException; lineNumber: 2; columnNumber: 6;
// 要素のコンテンツは、整形式の文字データまたはマークアップで構成されている必要があります。

abstract Properties getOutputProperties ()

変換のための出力プロパティのコピーを取得します。

final var xml = """
        <root><child>aaa</child></root>
        """;

final var builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
final var document = builder.parse(new ByteArrayInputStream(xml.getBytes()));

final var transformer = TransformerFactory.newInstance().newTransformer();

{
    final var ret = transformer.getOutputProperties();
    System.out.println(ret.size()); // 0

    final var source = new DOMSource(document);
    final var result = new StreamResult(new StringWriter());
    transformer.transform(source, result);

    //<?xml version="1.0" encoding="UTF-8" standalone="no"?><root><child>aaa</child></root>
    System.out.println(result.getWriter());
}

final var properties = new Properties();
properties.setProperty(OutputKeys.INDENT, "yes");
properties.setProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

transformer.setOutputProperties(properties);

{
    final var ret = transformer.getOutputProperties();
    System.out.println(ret); // {indent=yes, omit-xml-declaration=yes}

    final var source = new DOMSource(document);
    final var result = new StreamResult(new StringWriter());
    transformer.transform(source, result);

    //<root>
    //    <child>aaa</child>
    //</root>
    System.out.println(result.getWriter());
}

abstract String getOutputProperty (String name)

transformerに有効な出力プロパティを取得します。

final var xml = """
        <root><child>aaa</child></root>
        """;

final var builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
final var document = builder.parse(new ByteArrayInputStream(xml.getBytes()));

final var transformer = TransformerFactory.newInstance().newTransformer();

{
    System.out.println(transformer.getOutputProperty(OutputKeys.INDENT)); // "no"
    System.out.println(transformer.getOutputProperty(OutputKeys.OMIT_XML_DECLARATION)); // "no"

    final var source = new DOMSource(document);
    final var result = new StreamResult(new StringWriter());
    transformer.transform(source, result);

    //<?xml version="1.0" encoding="UTF-8" standalone="no"?><root><child>aaa</child></root>
    System.out.println(result.getWriter());
}

transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

{
    System.out.println(transformer.getOutputProperty(OutputKeys.INDENT)); // "yes"
    System.out.println(transformer.getOutputProperty(OutputKeys.OMIT_XML_DECLARATION)); // "yes"

    final var source = new DOMSource(document);
    final var result = new StreamResult(new StringWriter());
    transformer.transform(source, result);

    //<root>
    //    <child>aaa</child>
    //</root>
    System.out.println(result.getWriter());
}

abstract Object getParameter (String name)

setParameterを使用して明示的に設定されたパラメータを取得します。

このメソッドの使用例は、clearParameters() にまとめて記載しました。
そちらのAPI使用例をご参照ください。

abstract URIResolver getURIResolver ()

document()で使用されるURIを解決するのに使用されるオブジェクトを取得します。

final var sampleA = Path.of("R:", "java-work", "sample-a.xml");
System.out.println(sampleA); // R:\java-work\sample-a.xml

Files.writeString(sampleA, """
        <root>aaa</root>
        """);

final var sampleB = Path.of("R:", "java-work", "sample-b.xml");
System.out.println(sampleB); // R:\java-work\sample-b.xml

Files.writeString(sampleB, """
        <root>bbb</root>
        """);

final var xml = """
        <root/>
        """;

final var xsl = """
        <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
          <xsl:output omit-xml-declaration="yes" />
          <xsl:variable name="doc" select="document('file:///R:/java-work/sample-a.xml')" />

          <xsl:template match="/">
            <xsl:copy-of select="$doc" />
          </xsl:template>

        </xsl:stylesheet>
        """;

final var factory = TransformerFactory.newInstance();
final var transformer = factory.newTransformer(
        new StreamSource(new ByteArrayInputStream(xsl.getBytes())));

{
    System.out.println(transformer.getURIResolver()); // null

    final var source = new StreamSource(new ByteArrayInputStream(xml.getBytes()));
    final var result = new StreamResult(new StringWriter());
    transformer.transform(source, result);

    //<root>aaa</root>
    System.out.println(result.getWriter());
}

final var urlResolver = new URIResolver() {
    @Override
    public Source resolve(String href, String base) {
        if ("file:///R:/java-work/sample-a.xml".equals(href)) {
            return new StreamSource("file:///R:/java-work/sample-b.xml");
        }

        return null;
    }
};

transformer.setURIResolver(urlResolver);

{
    System.out.println(transformer.getURIResolver() == urlResolver); // true

    final var source = new StreamSource(new ByteArrayInputStream(xml.getBytes()));
    final var result = new StreamResult(new StringWriter());
    transformer.transform(source, result);

    //<root>bbb</root>
    System.out.println(result.getWriter());
}

void reset ()

このTransformerを元の構成にリセットします。

final var transformer = TransformerFactory.newInstance().newTransformer();

transformer.setParameter("param", "bbbb");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

System.out.println(transformer.getParameter("param")); // "bbbb"
System.out.println(transformer.getOutputProperty(OutputKeys.INDENT)); // "yes"
System.out.println(transformer.getOutputProperty(OutputKeys.OMIT_XML_DECLARATION)); // "yes"

transformer.reset();

System.out.println(transformer.getParameter("param")); // null
System.out.println(transformer.getOutputProperty(OutputKeys.INDENT)); // "no"
System.out.println(transformer.getOutputProperty(OutputKeys.OMIT_XML_DECLARATION)); // "no"

abstract void setErrorListener (ErrorListener listener)

変換に有効なエラー・イベント・リスナーを設定します。

このメソッドの使用例は、getErrorListener() にまとめて記載しました。
そちらのAPI使用例をご参照ください。

abstract void setOutputProperties (Properties oformat)

変換の出力プロパティを設定します。

このメソッドの使用例は、getOutputProperties() にまとめて記載しました。
そちらのAPI使用例をご参照ください。

abstract void setOutputProperty (String name, String value)

変換に有効な出力プロパティを設定します。

このメソッドの使用例は、getOutputProperty(String name) にまとめて記載しました。
そちらのAPI使用例をご参照ください。

abstract void setParameter (String name, Object value)

変換のパラメータを追加します。

このメソッドの使用例は、clearParameters() にまとめて記載しました。
そちらのAPI使用例をご参照ください。

abstract void setURIResolver (URIResolver resolver)

document()で使用されるURIを解決するのに使用されるオブジェクトを設定します。

このメソッドの使用例は、getURIResolver() にまとめて記載しました。
そちらのAPI使用例をご参照ください。

abstract void transform (Source xmlSource, Result outputTarget)

XML SourceをResultに変換します。

// DOM → XML文字列

final var builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
final var document = builder.newDocument();

final var root = document.createElement("root");
document.appendChild(root);

final var text = document.createTextNode("abcd");
root.appendChild(text);

final var transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

final var source = new DOMSource(document);
final var result = new StreamResult(new StringWriter());
transformer.transform(source, result);

//<root>abcd</root>
System.out.println(result.getWriter());
// XML文字列 → XSLによる変換

final var xml = """
        <root>abcd</root>
        """;

final var xsl = """
        <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
          <xsl:output omit-xml-declaration="yes" />

          <xsl:template match="/">012<xsl:value-of select="." />XYZ</xsl:template>

        </xsl:stylesheet>
        """;

final var transformer = TransformerFactory.newInstance().newTransformer(
        new StreamSource(new ByteArrayInputStream(xsl.getBytes())));

final var source = new StreamSource(new ByteArrayInputStream(xml.getBytes()));
final var result = new StreamResult(new StringWriter());
transformer.transform(source, result);

//012abcdXYZ
System.out.println(result.getWriter());
// DOM → SAX

final var builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
final var document = builder.newDocument();

final var root = document.createElement("root");
document.appendChild(root);

final var text = document.createTextNode("abcd");
root.appendChild(text);

final var transformer = TransformerFactory.newInstance().newTransformer();

final var handler = new DefaultHandler() {

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) {
        System.out.println("startElement : " + qName);
    }

    @Override
    public void endElement(String uri, String localName, String qName) {
        System.out.println("endElement : " + qName);
    }

    @Override
    public void characters(char[] ch, int start, int length) {
        System.out.println("text : " + new String(ch, start, length));
    }
};

final var source = new DOMSource(document);
final var result = new SAXResult(handler);

//startElement : root
//text : abcd
//endElement : root
transformer.transform(source, result);

関連記事

ページの先頭へ