fix(xslt): count the from boundary node in xsl:number level=single when it matches count (#270)
XSLT 1.0 7.7: for level=single the count node may be the from-boundary node itself when that node matches both the count and from patterns. The walk stopped at the nearest from-matching ancestor before testing it against count, so count="a|b" from="a" gave an empty number for a node inside an a. Test the count pattern before the boundary stops the walk. Closes Apache Xalan conformance case numbering63.
This commit is contained in:
parent
e7a8f473ef
commit
42a56abcbf
@ -52,6 +52,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Fixed
|
||||
|
||||
- `xsl:number level="single"` now counts the element that is the `from` boundary when that element also matches the `count` pattern (XSLT 1.0 7.7). The search for the count node stopped at the nearest `from`-matching ancestor before testing it against `count`, so a pattern like `count="a|b" from="a"` produced an empty number for an element inside an `a` (the count node is that `a`, which is also the boundary). The count pattern is now tested before the boundary stops the walk. Closes Apache Xalan conformance case `numbering63`.
|
||||
|
||||
- The `format` attribute of `xsl:number` is now evaluated as an attribute value template (XSLT 1.0 7.7), so `format="{$f}"` uses the value of `$f` rather than the literal string. It was stored and used verbatim, so a computed or passed-in format was never applied. Closes Apache Xalan conformance case `namedtemplate12`.
|
||||
|
||||
- A large integer-valued number now converts to a string with no decimal point (XPath 1.0 4.2). The number-to-string formatter only treated a value below 1e15 as an integer, so an integer such as `1234567890123456` (still exact in a double, which represents integers exactly up to 2^53) printed as `1234567890123456.0`. The integer bound is now 2^63, the range in which the conversion is safe. Closes Apache Xalan conformance case `string132`.
|
||||
|
||||
@ -42,10 +42,13 @@ enum XSLTNumbering {
|
||||
return [total]
|
||||
default: // single
|
||||
var current: Tree? = node
|
||||
while let candidate = current, !matchesFrom(candidate) {
|
||||
while let candidate = current {
|
||||
// The count node may be the from node itself when it matches both
|
||||
// patterns (7.7), so test count before stopping at the boundary.
|
||||
if matchesCount(candidate) {
|
||||
return [siblingPosition(of: candidate, matching: matchesCount)]
|
||||
}
|
||||
if matchesFrom(candidate) { break }
|
||||
current = candidate.parent
|
||||
}
|
||||
return []
|
||||
|
||||
@ -20,7 +20,6 @@ namespace/namespace19
|
||||
namespace/namespace23
|
||||
namespace/namespace24
|
||||
namespace/namespace35
|
||||
numbering/numbering63
|
||||
output/output22
|
||||
output/output26
|
||||
output/output63
|
||||
|
||||
@ -19,6 +19,21 @@ struct XSLTNumberingTests {
|
||||
return try PureXML.XSLT.transform(stylesheet: style, source: source)
|
||||
}
|
||||
|
||||
@Test("level=single counts the from node itself when it also matches count (7.7)")
|
||||
func test_singleFromCountOverlap() throws {
|
||||
// count and from both match `a`; a t's nearest count ancestor is its
|
||||
// parent a, which is also the from boundary, so it is still counted
|
||||
// (Apache Xalan numbering63).
|
||||
let style = """
|
||||
<xsl:stylesheet version="1.0" \(xsl)>
|
||||
<xsl:output omit-xml-declaration="yes"/>
|
||||
<xsl:template match="/"><out><xsl:apply-templates select="//t"/></out></xsl:template>
|
||||
<xsl:template match="t"><xsl:number level="single" count="a|b" from="a"/>,</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
"""
|
||||
#expect(try PureXML.XSLT.transform(stylesheet: style, source: "<doc><a><t/></a><a><t/></a></doc>") == "<out>1,2,</out>")
|
||||
}
|
||||
|
||||
@Test("the format attribute is an attribute value template (7.7)")
|
||||
func test_formatIsAVT() throws {
|
||||
// format="{$f}" evaluates the AVT, so a passed-in format string drives the
|
||||
|
||||
Loading…
Reference in New Issue
Block a user