Java : Transformer (XML) - API使用例
Transformer (Java SE 22 & JDK 22) の使い方まとめです。
ほとんどのメソッドにサンプルコードがあります。
API仕様書のおともにどうぞ。
概要
Transformerクラスは以下の変換を行います。
- XMLオブジェクト(DOMやSAX、StAX) → XML形式の文字列やファイル
- DOM → SAX などのXMLオブジェクト間の変換
- XSLT
関連記事 : XML (DOM) の基本操作
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());
コンストラクタ
Transformer ()
protectedです。
独自にサブクラスを作ることは少ないと思いますので、コード例は割愛します。
メソッド
abstract void clearParameters ()
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)
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 ret1 = transformer.getOutputProperty(OutputKeys.INDENT);
System.out.println(ret1); // "no"
final var ret2 = transformer.getOutputProperty(OutputKeys.OMIT_XML_DECLARATION);
System.out.println(ret2); // "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");
{
final var ret1 = transformer.getOutputProperty(OutputKeys.INDENT);
System.out.println(ret1); // "yes"
final var ret2 = transformer.getOutputProperty(OutputKeys.OMIT_XML_DECLARATION);
System.out.println(ret2); // "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)
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 URIResolver getURIResolver ()
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 ()
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)
// 意図的にエラーを起こすために、間違った構文の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 void setOutputProperties (Properties oformat)
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 void setOutputProperty (String name, String value)
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 ret1 = transformer.getOutputProperty(OutputKeys.INDENT);
System.out.println(ret1); // "no"
final var ret2 = transformer.getOutputProperty(OutputKeys.OMIT_XML_DECLARATION);
System.out.println(ret2); // "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");
{
final var ret1 = transformer.getOutputProperty(OutputKeys.INDENT);
System.out.println(ret1); // "yes"
final var ret2 = transformer.getOutputProperty(OutputKeys.OMIT_XML_DECLARATION);
System.out.println(ret2); // "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 void setParameter (String name, Object value)
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 void setURIResolver (URIResolver resolver)
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());
}
abstract void transform (Source xmlSource, Result outputTarget)
// 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);