Bug #5721
closedSaxon EE 10.8J optimizations break order of XPath selectors
100%
Description
Following XSLT fails on Saxon EE 10.8J using the default optimization level (-opt:10
). Turning the optimization off via -opt:0
returns correct results.
It seems, in this case the optimization does not keep the order of the XPath "selectors".
Error:
FORG0001 Cannot convert string "" to double
invoked by built-in template rule (text-only)
Cannot convert string "" to double
Test XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="#all" version="3.0" xmlns:saxon="http://saxon.sf.net/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:f="http://aimtec.cz/EDI" xmlns:aim="http://aimtec.cz/INT/mappingDescription">
<xsl:output encoding="UTF-8" indent="no" method="xml"/>
<xsl:template match="root">
<test>
<!-- Filter in order: name - content - numeric value -->
<xsl:for-each select="test/*[contains(name(), 'LieferscheinNummer')][. != ''][. != 0]">
<number>
<xsl:value-of select="."/>
</number>
</xsl:for-each>
</test>
</xsl:template>
</xsl:stylesheet>
Test input:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<test>
<LieferscheinNummer_1>1</LieferscheinNummer_1>
<LieferscheinNummer_2>0</LieferscheinNummer_2>
</test>
<test>
<LieferscheinNummer_1>2</LieferscheinNummer_1>
<LieferscheinNummer_2/>
</test>
</root>
Expected output:
<?xml version="1.0" encoding="UTF-8"?>
<test xmlns="http://www.w3.org/2005/xpath-functions">
<number>1</number>
<number>2</number>
</test>
Updated by Michael Kay about 2 years ago
Reordering of predicates is allowed by the XPath specification.
Whether it should be allowed is another matter - see https://github.com/qt4cg/qtspecs/issues/71
But at the moment, the spec allows it and Saxon takes advantage of the fact for optimisation. The only way to guarantee order of evaluation of conditionals is to use an if-then-else construct.
Updated by Michael Kay about 2 years ago
- Status changed from New to In Progress
- Assignee set to Michael Kay
- Applies to branch 11, trunk added
- Fix Committed on Branch 11, trunk added
- Platforms .NET added
As a quick fix, I'm adding an optimization flag so -opt:-p
will suppress this optimization. This will be in 12.x and the next maintenance release of 11.x.
Leaving the issue open, because I think a better (but more difficult) fix would be to do the optimization in such a way that reordering of predicates does not cause spurious errors.
Updated by Andy Yar about 2 years ago
Thank you for the explanation.
Changing the behavior for XSLT/XPath 4.0 would be great.
Updated by Michael Kay about 2 years ago
- Assignee deleted (
Michael Kay) - Applies to branch deleted (
11, trunk) - Fix Committed on Branch deleted (
11, trunk) - Platforms deleted (
.NET)
Updated by Michael Kay about 2 years ago
- Category set to Internals
- Assignee set to Michael Kay
- Applies to branch 11, trunk added
- Fix Committed on Branch 11, trunk added
- Platforms .NET added
Updated by Michael Kay almost 2 years ago
- Status changed from In Progress to Resolved
- Priority changed from Low to Normal
On the 11.x branch I added a partial fix that allows the optimization to be suppressed.
For 12.x, predicates can stll be reordered, but this should not generate any spurious errors. A composite filter expression A[P1][P2][P3]
is now rewritten as A[P1 and P2 and P3]
, and an "and" expression is evaluated so that if the first operand throws an error, we catch it and save it; if any operand is false, we return false and ignore the error, which means that re-ordering the operands no longer generates spurious errors.
So in the example given, test/*[contains(name(), 'LieferscheinNummer')][. != ''][. != 0]
we might still evaluate the predicates in reverse order, but we will only throw an error if contains(name(), 'LieferscheinNummer')]
is true.
Updated by Community Admin almost 2 years ago
- % Done changed from 0 to 100
- Fixed in Maintenance Release 12.0 added
Bug issue fix applied in the Saxon 12.0 Major Release. Leaving this bug marked as Resolved until fix applied
Updated by O'Neil Delpratt over 1 year ago
- Fixed in Maintenance Release 11.5 added
Bug applied in the Saxon 11.5 Maintenance release.
Updated by O'Neil Delpratt over 1 year ago
- Status changed from Resolved to Closed
Please register to edit this issue