Project

Profile

Help

Bug #5118

closed

Incorrect handling of multiple xsl:mode declarations for the same mode

Added by Martin Honnen about 3 years ago. Updated over 2 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
XSLT conformance
Sprint/Milestone:
-
Start date:
2021-10-08
Due date:
% Done:

100%

Estimated time:
Legacy ID:
Applies to branch:
10, 11
Fix Committed on Branch:
10, trunk
Fixed in Maintenance Release:
Platforms:
.NET, Java

Description

When I try to run a streamable transformation where I have the streamable declaration first in a single <xsl:mode streamable="yes"/> and later on a second xsl:mode with e.g. <xsl:mode on-no-match="shallow-copy"/> both Saxon EE 10.6 Java and SaxonCS 11 EE seem to build a tree based on the TIMING or -t output.

Simple repro: XML:

<root>
  <data>This is a test.</data>
</root>

XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="#all"
  expand-text="yes">

  <xsl:mode streamable="yes"/>

  <xsl:template match="/" name="xsl:initial-template">
    <xsl:next-match/>
    <xsl:comment>Run with {system-property('xsl:product-name')} {system-property('xsl:product-version')} {system-property('Q{http://saxon.sf.net/}platform')}</xsl:comment>
  </xsl:template>

 <xsl:mode on-no-match="shallow-copy"/>

</xsl:stylesheet>

Output with Saxon EE 10.6 from the command line:

PS C:\Users\marti\OneDrive\Documents\xslt\xslt4-examples\streamable-identity> java -jar 'C:\Program Files\Saxonica\SaxonEE10-6J\saxon-ee-10.6.jar' -t -s:.\input-sample1.xml -xsl:.\identity-streamable-two-separate-mode-declarations1.xsl
Saxon-EE 10.6J from Saxonica
Java version 1.8.0_292
Using license serial number V.....
Stylesheet compilation time: 615.5411ms
Processing file:/C:/Users/marti/OneDrive/Documents/xslt/xslt4-examples/streamable-identity/./input-sample1.xml
Using parser com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser
Building tree for file:/C:/Users/marti/OneDrive/Documents/xslt/xslt4-examples/streamable-identity/./input-sample1.xml using class net.sf.saxon.tree.tiny.TinyBuilder
Tree built in 3.1059ms
Tree size: 6 nodes, 15 characters, 0 attributes
<?xml version="1.0" encoding="UTF-8"?><root>
  <data>This is a test.</data>
</root><!--Run with SAXON EE 10.6 -->Execution time: 88.7911ms
Memory used: 62Mb

Output with SaxonCS:

PS C:\Users\marti\OneDrive\Documents\xslt\xslt4-examples\streamable-identity> & 'C:\Program Files\Saxonica\SaxonCS-11.0\SaxonCS.exe' transform -t -s:.\input-sample1.xml -xsl:.\identity-streamable-two-separate-mode-declarations1.xsl
SaxonCS-EE 11.0 from Saxonica
.NET 5.0.9 on Windows 10.0.19043.0
Using license serial number V.....
Stylesheet compilation time: 566,8583ms
Processing file:///C:/Users/marti/OneDrive/Documents/xslt/xslt4-examples/streamable-identity/input-sample1.xml
Building tree for file:///C:/Users/marti/OneDrive/Documents/xslt/xslt4-examples/streamable-identity/input-sample1.xml using Saxon.Hej.tree.tiny.TinyBuilder
Tree built in 5,9621ms
Tree size: 6 nodes, 65536 characters, 0 attributes
<?xml version="1.0" encoding="UTF-8"?><root>
  <data>This is a test.</data>
</root><!--Run with SAXON EE 11.0 -->Execution time: 100,9325ms
Memory used: 0Mb
Actions #1

Updated by Martin Honnen about 3 years ago

If the two xsl:mode declarations are reordered to have the one with the explicit streamable="yes" last, as in

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="#all"
  expand-text="yes">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:template match="/" name="xsl:initial-template">
    <xsl:next-match/>
    <xsl:comment>Run with {system-property('xsl:product-name')} {system-property('xsl:product-version')} {system-property('Q{http://saxon.sf.net/}platform')}</xsl:comment>
  </xsl:template>

  <xsl:mode streamable="yes"/>

</xsl:stylesheet>

then both Saxon EE 10.6 Java and SaxonCS EE 11 stream.

So the order seems to perhaps in the first, not streamed test case make Saxon use the implicit default of streamable="no" of the second xsl:mode declaration.

But my reading of the spec's text "For the unnamed mode, the effective value of each attribute is taken from an xsl:mode declaration that has no name attribute, and that specifies an explicit value for the required attribute. If there is no such declaration, the default value of the attribute is used. If there is more than one such declaration, the one with highest import precedence is used." is that, as long as there is an xsl:mode with an explicit streamable="yes" and no later, higher import precedence explicit streamable="no", that the explicit streamable="yes" defines the effective value.

Actions #2

Updated by Michael Kay about 3 years ago

The following query:

-qs:"collection('/Users/mike/GitHub/xslt30-test/tests/attr/mode?select=*.xsl')[count(distinct-values(//*:mode/string(@name))) lt count(//*:mode)]/base-uri(.)"

demonstrates that there is only one test (mode-1502) that has more than one mode with the same name; and that is testing the error case where there are conflicting values for the same attribute.

So the whole area is grossly under-tested.

The Saxon implementation in XSLMode (a) succeeds in creating a single Mode object corresponding to the multiple xsl:mode elements, and (b) (in the validate() method) creates a data structure representing the properties of these modes, identifying conflicts and identifying the one with highest import precedence. But the prepareAttributes() method updates the properties of the mode directly, ignoring this data structure, and the properties are also accessed directly.

Actions #3

Updated by Michael Kay about 3 years ago

  • Status changed from New to In Progress

I'm tackling this by moving some of the logic for setting properties of a mode from XSLMode.prepareAttributes() to SimpleMode.checkForConflictingProperties().

I'm now getting a couple of test failures because TemplateRule.isDeclaredStreamable() is (apparently) being called before the relevant property of the Mode object has been computed.

Actions #4

Updated by Michael Kay about 3 years ago

Fixed this by moving the call on ruleManager.checkConsistency() to come earlier in the sequence of tasks performed by PrincipalStylesheetModule.compile().

Now getting xslt30 test failures:

Failures by Test Set: 
  error : 1 (error-0540a)
  match : 3 (-082b, -082c, -260)
Actions #5

Updated by Michael Kay about 3 years ago

That's now fixed - I overlooked on-multiple-match="fail" in the checkConsistency() logic.

The other thing missing from that code is handling of the visibility attribute. I think that needs some extra tests.

Actions #6

Updated by Michael Kay about 3 years ago

  • Subject changed from Saxon builds tree although there is an explicit xsl:mode streamable="yes" to Incorrect handling of multiple xsl:mode declarations for the same mode
Actions #7

Updated by Michael Kay about 3 years ago

  • Status changed from In Progress to Resolved
  • Assignee set to Michael Kay
  • Fix Committed on Branch 10, trunk added
Actions #8

Updated by O'Neil Delpratt almost 3 years ago

  • % Done changed from 0 to 100
  • Fixed in Maintenance Release 11.1 added
  • Platforms .NET, Java added

Bug fix applied in the Saxon 11.1 release.

Actions #9

Updated by O'Neil Delpratt almost 3 years ago

Leaving bug as resolved until fix applied to the Saxon 10 maintenance release.

Actions #10

Updated by Debbie Lockett over 2 years ago

  • Status changed from Resolved to Closed
  • Fixed in Maintenance Release 10.7 added
  • Fixed in Maintenance Release deleted (11.1)

Bug fix applied in the Saxon 10.7 maintenance release.

Actions #11

Updated by Debbie Lockett over 2 years ago

  • Fixed in Maintenance Release 11.1 added

Please register to edit this issue

Also available in: Atom PDF