user1030620 user1030620 - 13 days ago 5
Java Question

JAVA Transformation returns XSLT instead of transformation result

I try to use Java Transformer with org.w3c.dom.Document for input, output and the XSLT. Unfortunately the output is equal to the XSLT input. So it seems the transformation isn't used correctly. I wasn't able to find any reason for this behavior, so I ask it here and hope for help.

My Code:

import java.io.BufferedReader;
import java.io.FileReader;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.sql.SQLException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class XMLTransform {
public static void main(String[] args) {

StringWriter stringWriter = null;
try {
// Read Input Files
Document xslt = parseXML(readFile("...")); // link to XSLT
Document input = parseXML(readFile("...")); // link to input

// Create new Transformer with the XSLT
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(new DOMSource(xslt));

// create variables for the output
stringWriter = new StringWriter();
StreamResult streamResult = new StreamResult(stringWriter);

// transform
transformer.transform(new DOMSource(input), streamResult);

// parse it to XML DOM File
Document resultXML = parseXML(stringWriter.toString());

// output, so we see it is wrong
System.out.println(convertDocumentToString(resultXML));
} catch (Exception e) {
} finally {
try {
if (stringWriter != null) stringWriter.close();
} catch (Exception e1) { };
}
}

//////////////////////////////////////
//Helper-Methods which seems to work//
//////////////////////////////////////

public static String convertDocumentToString(Document doc) throws TransformerFactoryConfigurationError,
TransformerException {
Transformer tf = TransformerFactory.newInstance().newTransformer();
tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
tf.setOutputProperty(OutputKeys.INDENT, "yes");
Writer out = new StringWriter();
tf.transform(new DOMSource(doc), new StreamResult(out));
return out.toString();
}

private static Document parseXML(String str) throws ParserConfigurationException, SAXException, IOException,
SQLException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(new InputSource(new StringReader(str)));
}

private static String readFile(String filename) throws Exception {
BufferedReader br = new BufferedReader(new FileReader(filename));
try {
StringBuilder sb = new StringBuilder();
String line = br.readLine();

while (line != null) {
sb.append(line);
line = br.readLine();
}
return sb.toString();
} finally {
br.close();
}
}
}


And I use following input files:

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="/">
<xsl:apply-templates select="/Test/Content"/>
</xsl:template>

<xsl:template match="/Test/Content">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>


Input-File:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Test>
<Content>
<X>x</X>
<Y>y</Y>
<Z>z</Z>
</Content>
<Template>
<Definition>
<A>A</A>
<B>B</B>
<C>C</C>
</Definition>
</Template>
</Test>


And I get the strange output (equal to the XSLT)

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output encoding="UTF-8" indent="yes" method="xml" version="1.0"/>
<xsl:template match="/">
<xsl:apply-templates select="/Test/Content"/>
</xsl:template>
<xsl:template match="/Test/Content">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>


Does anybody know, why the output is equal to the XSLT-File, and how to fix it? So that it returns the correct transformed XML instead?

Thanks

Answer

Make sure you do

factory.setNamespaceAware(true);

when working with XSLT (both stylesheets as well as input documents).

Comments