I am passing a simple string parameter to my Saxon-driven XSLT, but it is not getting picked up.
Here's the XSL (min.xsl
):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:template match="/">
<xsl:param name="in"/>
<Out>
<xsl:choose>
<xsl:when test="Val = $in">match!</xsl:when>
<xsl:otherwise>
<xsl:value-of select="Val"/> != <xsl:value-of select="$in"/>
</xsl:otherwise>
</xsl:choose>
</Out>
</xsl:template>
</xsl:stylesheet>
Here's the code used to invoke the XSLT:
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.FileInputStream;
import java.io.StringReader;
public class MinXSLT {
public static void main(String[] args) throws Exception {
try {
Class.forName("net.sf.saxon.TransformerFactoryImpl");
System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");
System.out.println("Plugged in Saxon");
} catch (ClassNotFoundException ignore) {}
final TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer e = transformerFactory.newTemplates(new StreamSource(new FileInputStream("src/test/resources/min.xsl"))).newTransformer();
e.setParameter("in", "x");
e.transform(new StreamSource(new StringReader("<Val>x</Val>")), new StreamResult(System.out));
}
}
Here's the dependencies
section of my pom.xml
:
<dependencies>
<dependency>
<groupId>saxon</groupId>
<artifactId>saxon-he</artifactId>
<version>9.2</version>
</dependency>
</dependencies>
Yup, just saxon-he
.
Strangely, when I remove the Saxon dependency, the parameter gets picked up and I get the expected result:
<?xml version="1.0" encoding="UTF-8"?><Out>match!</Out>
But when Saxon is in use, I get the 'parameter mismatch' result with an empty string in place of the parameter value:
Plugged in Saxon
<?xml version="1.0" encoding="UTF-8"?><Out>x != </Out>
What is my crime here?
For the record, I tried using newer versions of Saxon (net.sf.saxon:Saxon-HE:9.7.x
etc.), with the same result; however in the actual project I am stuck with saxon:saxon-he:9.2
so upgrading is not really an option.
You need to move the <xsl:param name="in"/>
outside of any xsl:template
to have it as a global parameter you can set before the transformation. xsl:param
s inside templates are not settable by the JAXP transformation API, in XSLT 3 with Saxon's API you could call a named template or function directly and set its parameters when doing so but your approach with applying templates to a Source in JAXP is not meant for that. Simply use a global parameter, i.e. move the xsl:param
outside of any xsl:template
and make it a child of xsl:stylesheet/xsl:transform
.