Project

Profile

Help

Bug #4959

xsl:output/@method overrides xsl:result-document/@method when delivery-format=serialized

Added by Evan Lenz 6 months ago. Updated 5 months ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Serialization
Sprint/Milestone:
-
Start date:
2021-04-01
Due date:
% Done:

100%

Estimated time:
Legacy ID:
Applies to branch:
10, trunk
Fix Committed on Branch:
10, trunk
Fixed in Maintenance Release:

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 output

Actual 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.

run-test.xsl (1.15 KB) run-test.xsl Evan Lenz, 2021-04-01 07:43
test.xsl (670 Bytes) test.xsl Evan Lenz, 2021-04-01 07:43

History

#1 Updated by Evan Lenz 6 months 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.

#2 Updated by Martin Honnen 6 months 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.

#3 Updated by Michael Kay 6 months 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().

#4 Updated by Evan Lenz 6 months 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.

#5 Updated by Michael Kay 6 months 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.

#6 Updated by Michael Kay 6 months 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.

#7 Updated by Michael Kay 5 months 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.

#8 Updated by O'Neil Delpratt 5 months 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

Also available in: Atom PDF