问题
I have following XSL stylesheet:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
<xsl:output encoding="UTF-8" method="xml"/>
<xsl:template match="/">
<test/>
</xsl:template>
</xsl:stylesheet>
I am using Saxon 9.9 to transform it like this.
public String transform(InputStream input, InputStream stylesheet, OutputStream output){
Processor p = new Processor(false);
XsltCompiler c = p.newXsltCompiler();
XsltExecutable e = c.compile(new StreamSource(stylesheet));
Xslt30Transformer xf = e.load30();
Serializer s = p.newSerializer(output);
xf.transform(new StreamSource(input), s);
return s.getOutputProperty(Serializer.Property.ENCODING));
}
I would expect the return value to be "UTF-8" as specified in the stylesheet, but it returns null instead. (The serializer instance seems to have no properties at all.) Why is this, and what is the correct way to get the output properties?
回答1:
The interface between the XSLT transformation engine and the serializer is unfortunately very messy. It's messy in the XSLT spec, it's messy in JAXP, and it's messy in Saxon. I've made a number of attempts over the years to improve it, but it's still messy. There were some changes in Saxon 9.9, made necessary by the new and innocent-seeming (and in XSLT, almost useless) item-separator
attribute, which has the effect that composing individual items into a document tree (if it happens at all) has to happen on the serialization side of the boundary, not on the transformation side.
The situation in the Saxon 9.9 s9api interface is that (in general) the Serializer object knows nothing about the serialization properties defined in the stylesheet, it only knows about those supplied directly via the Serializer API. Only when the Transformer invokes the Serializer to perform serialization do the two sets of serialization properties get combined.
The exception is when you use Xslt30Transformer.newSerializer()
to create the serializer. In that case the serializer is initialized with the properties defined in unnamed xsl:output
declarations in the stylesheet, as if they were set explicitly using serializer.setOutputProperty()
.
The serialization properties defined in the stylesheet are available (though not very directly) as properties of the s9api XsltExecutable
. This has a method getUnderlyingCompiledStylesheet()
which returns a PreparedStylesheet
object, and this has a method getDeclaredSerializationProperties()
which returns properties defined on the default (unnamed) xsl:output
declarations. There is also a method getOutputProperties(name)
which returns properties for a named output format (as used in xsl:result-document
)
来源:https://stackoverflow.com/questions/53801890/getting-the-serialization-properties-from-saxon-transformation