Javax.xml.transform.Transformer ignoring prefixes?
I am trying to parse a very simple example:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/'>
<openSearch:totalResults>100</openSearch:totalResults>
</root>
The stylesheet I am using is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:app='http://www.w3.org/2007/app' >
<xsl:output method="xml" indent="yes"/>
<xsl:preserve-space elements="*"/>
<xsl:template match="/">
<results>
<xsl:attribute name="total-results">
<xsl:value-of
select="atom:root/openSearch:totalResults"/>
</xsl:attribute>
</results>
</xsl:template>
</xsl:stylesheet>
This works in libxslt, no problem. I am trying to accomplish the same task in java now and I am trying to use the javax.xml.transform package to do this. Instead of the expected result, it provides an empty value for the total-results attribute. However, when I change the value to this:
<xsl:value-of select="root/totalResults"/>
It works. Changing xml and xslt is not an option. Is there a parameter I should be setting somewhere? The code is pretty simple:
InputSource xmlSource = new InputSource( new StringReader(xml) );
DocumentBuilder builder = factory.newDocumentBuilder();
document = builder.parse(xmlSource);
// Use a Transformer for output
TransformerFactory tFactory = TransformerFactory.newInstance();
StreamSource stylesource = new StreamSource(new StringReader(styleSheet));
Transformer transformer = tFactory.newTransformer(stylesource);
StringWriter writer = new StringWriter();
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(writer);
transformer.transform(source, result);
stringResult = writer.toString();
+3
source to share
1 answer
You are missing the namespace declarations for "atom" and "openSearch" in the stylesheet. The following works:
- Add openSearch namespace (copied from xml) to your stylesheet
- Remove the namespace "atom" as there is no information about it Namespace
- Set the factory as a namespace:
factory.setNamespaceAware(true);
Here is the complete code in Scala (sorry I was too lazy, parsing xml and stylesheet from a file, or doing string concatenation in Java):
def testxsl = {
val xml = """<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/'>
<openSearch:totalResults>100</openSearch:totalResults>
</root>
"""
val styleSheet = """<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:app='http://www.w3.org/2007/app'
xmlns:openSearch='http://a9.com/-/spec/opensearch/1.1/'>
<xsl:output method="xml" indent="yes"/>
<xsl:preserve-space elements="*"/>
<xsl:template match="/">
<results>
<xsl:attribute name="total-results">
<xsl:value-of select="root/openSearch:totalResults"/>
</xsl:attribute>
</results>
</xsl:template>
</xsl:stylesheet>
"""
val xmlSource = new InputSource( new StringReader(xml) );
val factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
val builder = factory.newDocumentBuilder();
val document = builder.parse(xmlSource);
// Use a Transformer for output
val tFactory = TransformerFactory.newInstance();
val stylesource = new StreamSource(new StringReader(styleSheet));
val transformer = tFactory.newTransformer(stylesource);
val writer = new StringWriter();
val source = new DOMSource(document);
val result = new StreamResult(writer);
transformer.transform(source, result);
writer.toString();
}
+5
source to share