XSLT transformation using DOMSource & DOMResult
Just reminder. really hit a wall.
The points are following two. It's no problem if the source is always String, but sometimes not somehow.
- need to do DocumentBuilderFactory#setNamespaceAware(true) when creating DOMSource from String, or XSLT transformation fails afterward. And what is worse, it doesn't return a error but empty result.
- DOMResult#getNode() actually returns Document, so need to do like this - ((Document)domresult.getNode()).getDocumentElement() - I don't like this. use getDocument() as method name if it returns the Document.
XsltTransformTest.java - Testcase using StreamSource, StreamResult as well
import java.io.StringReader; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Result; import javax.xml.transform.Source; import javax.xml.transform.Templates; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import org.w3c.dom.Document; import org.xml.sax.InputSource; public class XsltTransformTest { private static final String XML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<orders:order xmlns:orders=\"urn:switchyard-quickstart:transform-xslt:1.0\">\n" + " <orderId>PO-19838-XYZ</orderId>\n" + " <itemId>BUTTER</itemId>\n" + " <quantity>200</quantity>\n" + "</orders:order>"; private static final String XSLT = "<?xml version=\"1.0\"?>\n" + "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n" + " <xsl:template match=\"/\">\n" + " <orders:orderAck xmlns:orders=\"urn:switchyard-quickstart:transform-xslt:1.0\">\n" + " <xsl:for-each select=\"orders:order\">\n" + " <orderId>\n" + " <xsl:value-of select=\"orderId\" />\n" + " </orderId>\n" + " <accepted>\n" + " <xsl:choose>\n" + " <xsl:when test=\"(itemId = 'BUTTER') and (quantity <= 200)\">\n" + " true\n" + " </xsl:when>\n" + " <xsl:otherwise>\n" + " false\n" + " </xsl:otherwise>\n" + " </xsl:choose>\n" + " </accepted>\n" + " <status>\n" + " <xsl:choose>\n" + " <xsl:when test=\"(itemId = 'BUTTER') and (quantity <= 200)\">\n" + " Order Accepted\n" + " </xsl:when>\n" + " <xsl:when test=\"itemId != 'BUTTER'\">\n" + " No Such Item:\n" + " <xsl:value-of select=\"itemId\" />\n" + " </xsl:when>\n" + " <xsl:when test=\"quantity > 200\">\n" + " Not Enough Stock\n" + " </xsl:when>\n" + " <xsl:otherwise>\n" + " UNKNOWN\n" + " </xsl:otherwise>\n" + " </xsl:choose>\n" + " </status>\n" + " </xsl:for-each>\n" + " </orders:orderAck>\n" + " </xsl:template>\n" + "</xsl:stylesheet>"; public static void main(String[] args) throws Exception { new XsltTransformTest().perform(); } public void perform() throws Exception { System.out.println("* * * StreamSource => StreamResult * * *"); transform(XSLT, createStreamSource(XML), new StreamResult(System.out)); System.out.println("\n* * * DOMSource => StreamResult * * *"); transform(XSLT, createDOMSource(XML), new StreamResult(System.out)); DOMResult result = new DOMResult(); System.out.println("\n* * * StreamSource => DOMResult * * *"); printDOMResult(transform(XSLT, createStreamSource(XML), result)); result = new DOMResult(); System.out.println("\n* * * DOMSource => DOMResult * * *"); printDOMResult(transform(XSLT, createDOMSource(XML), result)); } private void printDOMResult(DOMResult dom) throws Exception { System.out.println("getNode().getLocalName()=" + dom.getNode().getLocalName() + ", ((Document)getNode()).getDocumentElement().getLocalName()=" + ((Document)dom.getNode()).getDocumentElement().getLocalName()); } private <T extends Result> T transform(String xslt, Source source, T result) throws Exception { javax.xml.transform.TransformerFactory tFactory = javax.xml.transform.TransformerFactory.newInstance(); Templates templates = tFactory.newTemplates(new StreamSource(new StringReader(xslt))); javax.xml.transform.Transformer transformer = templates.newTransformer(); transformer.transform(source, result); return result; } private DOMSource createDOMSource(String str) throws Exception { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); InputSource input = new InputSource(new StringReader(str)); Document document = factory.newDocumentBuilder().parse(input); return new DOMSource(document.getDocumentElement()); } private StreamSource createStreamSource(String str) throws Exception { return new StreamSource(new StringReader(str)); } }
output
* * * StreamSource => StreamResult * * * <?xml version="1.0" encoding="UTF-8"?><orders:orderAck xmlns:orders="urn:switchyard-quickstart:transform-xslt:1.0"><orderId>PO-19838-XYZ</orderId><accepted> true </accepted><status> Order Accepted </status></orders:orderAck> * * * DOMSource => StreamResult * * * <?xml version="1.0" encoding="UTF-8"?><orders:orderAck xmlns:orders="urn:switchyard-quickstart:transform-xslt:1.0"><orderId>PO-19838-XYZ</orderId><accepted> true </accepted><status> Order Accepted </status></orders:orderAck> * * * StreamSource => DOMResult * * * getNode().getLocalName()=null, ((Document)getNode()).getDocumentElement().getLocalName()=orderAck * * * DOMSource => DOMResult * * * getNode().getLocalName()=null, ((Document)getNode()).getDocumentElement().getLocalName()=orderAck