Bug #4959
closedxsl:output/@method overrides xsl:result-document/@method when delivery-format=serialized
100%
Description
When invoking a stylesheet via transform() and setting delivery-format to "serialized", the xsl:output/@method of the invoked stylesheet overrides any and all xsl:result-document/@method values.
If you run test.xsl (against any document), it produces the expected serialization for each xsl:result-document (secondary1.txt and secondary2.xml), honoring xsl:result-document/@method regardless of what xsl:output/@method says. This is what I would expect.
But if you invoke test.xsl via run-test.xsl, the xsl:result-document/@method values are ignored, and the xsl:output/@method overrides them all. This seems wrong.
Expected primary output:
main outputActual primary output: main output
Expected content of secondary-outputs.xml: text doc xml doc
Actual content of secondary-outputs.xml: text doc xml doc
If you try changing the xsl:output/@method (in test.xsl) to "xml" instead of "text", running test.xsl by itself still produces the expected results, but invoking it via transform() (in run-test.xsl) causes the same problem: the xsl:result-document/@method values are ignored.
Expected content of secondary-outputs.xml after changing xsl:output/@method to "xml" is the same as the expected content listed above.
Actual content of secondary-outputs.xml after changing xsl:output/@method to "xml": text doc xml doc
I suspect this is a bug. I got the same behavior in both Saxon-HE 9.9.1.4J and Saxon-HE 10.3J.
Files
Updated by Evan Lenz over 3 years ago
[Aargh, let me try that again. I should have looked more closely at the Preview. Sorry about that!]¶
When invoking a stylesheet via transform() and setting delivery-format to "serialized", the xsl:output/@method of the invoked stylesheet overrides any and all xsl:result-document/@method values.
If you run test.xsl (against any document), it produces the expected serialization for each xsl:result-document (secondary1.txt and secondary2.xml), honoring xsl:result-document/@method regardless of what xsl:output/@method says. This is what I would expect.
But if you invoke test.xsl via run-test.xsl, the xsl:result-document/@method values are ignored, and the xsl:output/@method overrides them all. This seems wrong.
Expected primary output:
<?xml version="1.0" encoding="UTF-8"?><principal>main output</principal>
Actual primary output:
main output
Expected content of secondary-outputs.xml:
<secondary-outputs>text doc <secondary2>xml doc</secondary2></secondary-outputs>
Actual content of secondary-outputs.xml:
<secondary-outputs>text doc xml doc</secondary-outputs>
If you try changing the xsl:output/@method (in test.xsl) to "xml" instead of "text", running test.xsl by itself still produces the expected results, but invoking it via transform() (in run-test.xsl) causes the same problem: the xsl:result-document/@method values are ignored.
Expected content of secondary-outputs.xml after changing xsl:output/@method to "xml" is the same as the expected content listed above.
Actual content of secondary-outputs.xml after changing xsl:output/@method to "xml":
<secondary-outputs><?xml version="1.0" encoding="UTF-8"?><secondary1>text doc</secondary1> <secondary2>xml doc</secondary2></secondary-outputs>
I suspect this is a bug. I got the same behavior in both Saxon-HE 9.9.1.4J and Saxon-HE 10.3J.
Updated by Martin Honnen over 3 years ago
Interesting combination of XSLT calling XSLT, Saxon JS 2 indeed manages to produce the expected result <secondary-outputs>text doc <secondary2>xml doc</secondary2></secondary-outputs>
for secondary-outputs.xml.
Updated by Michael Kay over 3 years ago
I've set this up as XSLT4 test case transform/transform-009.
The case where xsl:result-document
is called with no href is a tricky path and it looks as if it's not working properly when the transformation is called via fn:transform(). I think what's happening is that the fn:transform()
code looks at the principal output properties of the transformation and supplies them as API-supplied serialization properties, and API-supplied serialization properties trump those specified on xsl:result-document
.
In more detail, what happens here is that the call on xsl:result-document
with no @href
results in a call of PrincipalOutputGatekeeper.getReceiver()
, which calls Serializer.getReceiver()
, which merges the supplied parameters (including method=xml
) with the parameters already present on the serializer (including method=text
), but giving precedence to the values already on the Serializer
.
Perhaps I need to look at how we make this work in the case where the transformation is NOT called via fn:transform()
.
Updated by Evan Lenz over 3 years ago
I don't know if this matters too much, but the xsl:result-document
with no href was a part of the test case I posted but not a part of the use case where I ran into the problem. The use case is pre-processing another user's stylesheet (by adding the creation of secondary outputs for tracing & visualization purposes). Those secondary output documents should always be XML, but if the user's stylesheet specified method="text"
on xsl:output
, that's when the problem arises. My workaround is to require the user of the visualization tool to pass a principal-output-method
parameter to the pre-processor, rather than detect it automatically from the original stylesheet. I guess what I want to emphasize is that the problem isn't unique to xsl:result-document
with no href.
Updated by Michael Kay over 3 years ago
- Category set to Serialization
- Status changed from New to In Progress
- Assignee set to Michael Kay
I have fixed this test case by changing the fn:transform()
code to create a serializer using Processor.newSerializer()
rather than XsltTransformer.newSerializer()
. However, this is causing regression in test case QT3/fn-transform.fn-transform-67,
which I now need to investigate.
Updated by Michael Kay over 3 years ago
Test fn-transform-67
is failing because SerializationProperties.combineWith()
makes no attempt to combine two character maps.
Prior to the change, this merging of character maps was done by TransformFn.makeSerializer()
I'm now looking to see how character maps are merged when xsl:result-document
overrides xsl:output
. This is tested by XSLT3 test case result-document-0241. It seems that in this test case the merging is done by the logic in ResultDocument.setSerializationProperty
. (Note that it doesn't actually create a merged map, it simply sets the use-character-maps
property to a space-separated list of character map names containing first the xsl:output
value and then the xsl:result-document
value).
Using the same technique in SerializationProperties.combineWith()
(concatenating the properties, as with cdata-section-elements
) appears to solve the problem, subject to further regression testing.
Updated by Michael Kay over 3 years ago
- Status changed from In Progress to Resolved
- Applies to branch 10, trunk added
- Fix Committed on Branch 10, trunk added
Now resolved with the changes outlined above.
Updated by O'Neil Delpratt over 3 years ago
- Status changed from Resolved to Closed
- % Done changed from 0 to 100
- Fixed in Maintenance Release 10.5 added
Bug fix applied to Saxon 10.5 maintenance release.
Please register to edit this issue