Difference between parameters with "as" attribute type declaration in xsl:function and xsl:iterate?
Added by Martin Honnen over 4 years ago
Using Saxon (tested with HE 10 but also found in 9.8 and 9.9), I have found a strange result using xsl:iterate
with an iteration parameter declaring a type with e.g. as="xs:string"
. When I do this with functions or templates I am used to any node values being atomized while Saxon with xsl:iterate
seems to either include the node or serialize it as XML.
An example stylesheet is
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
xmlns:mf="http://example.com/mf"
expand-text="yes"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes" />
<xsl:template match="/" name="xsl:initial-template">
<xsl:iterate select="1 to 5">
<xsl:param name="p1" as="xs:string" select="'test'"/>
<xsl:on-completion>
<xsl:copy-of select="count($p1), $p1 instance of xs:string"/>
<xsl:copy-of select="$p1"/>
<xsl:copy-of select="$p1[1]"/>
<xsl:value-of select="boolean($p1), string-length($p1) ne 0"/>
</xsl:on-completion>
<xsl:next-iteration>
<xsl:with-param name="p1">
<xsl:copy-of select="$p1"/>
<item>test {.}</item>
</xsl:with-param>
</xsl:next-iteration>
</xsl:iterate>
<function-call>
<xsl:sequence select="mf:test((1 to 5), 'test')"/>
</function-call>
</xsl:template>
<xsl:function name="mf:test">
<xsl:param name="seq" as="item()*"/>
<xsl:param name="p1" as="xs:string"/>
<xsl:choose>
<xsl:when test="empty($seq)">
<xsl:sequence select="$p1"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="item" as="element(item)"><item>Test {head($seq)}</item></xsl:variable>
<xsl:variable name="p1">
<xsl:copy-of select="$p1, $item"/>
</xsl:variable>
<xsl:sequence select="mf:test(tail($seq), $p1)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
</xsl:stylesheet>
which outputs
<?xml version="1.0" encoding="UTF-8"?>1 truetest<item>test 1</item>
<item>test 2</item>
<item>test 3</item>
<item>test 4</item>
<item>test 5</item>test<item>test 1</item>
<item>test 2</item>
<item>test 3</item>
<item>test 4</item>
<item>test 5</item>true true<function-call>testTest 1Test 2Test 3Test 4Test 5</function-call>
with Saxon 10 HE for me while Exselt
<?xml version="1.0" encoding="UTF-8"?>1 true testtest 1test 2test 3test 4test 5 testtest 1test 2test 3test 4test 5true t
rue<function-call>testTest 1Test 2Test 3Test 4Test 5</function-call>
So for some reason the item
element nodes passed in xsl:iterate
to the p1
variable type as="xs:string"
are being bound as nodes or as serialized <item>test x</item>
while with a function Saxon does what I exepct and what Exselt does in both cases, namely just take the string value of the node.
I understand Exselt never got published adjusted to the final spec but I can't find anything in the XSLT 3 spec explaining Saxon's result for the values of $p
in xsl:iterate
containing all those <item>test n</item>
.
Replies (1)
RE: Difference between parameters with "as" attribute type declaration in xsl:function and xsl:iterate? - Added by Michael Kay over 4 years ago
Thanks for reporting this, I have raised it here:
Please register to reply