There are cases when position() appearing in a predicate
should be optimized.
The common use case is when selecting the first n
nodes, as is often done when grouping: [position() <= $n]
The evaluator should know that it does not need to test
nodes whose positions are > $n.
python
f = open('22000.xml','w')
f.write('<?xml version="1.0" encoding="utf-8"?>')
f.write('<top>')
for i in range(22000):
f.write('<x>' + str(i) + '</x>')
f.write('</top>')
f.close()
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml"/>
<xsl:template match="/">
<xsl:for-each select="top/x[position() mod 3 = 1]">
<xsl:text>&#xA;</xsl:text>
<w>
<xsl:copy-of select=".|following-sibling::x[position()
&lt; 3]"/>
</w>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
/usr/bin/time 4xslt -o /dev/null 22000.xml 22000.xsl
7355.09 real 6797.17 user 3.05 sys
usr/bin/time java org.apache.xalan.xslt.Process -IN
22000.xml -XSL 22000.xsl -OUT /dev/null
270.29 real 188.18 user 1.04 sys
/usr/bin/time java com.icl.saxon.StyleSheet -o /dev/null
22000.xml 22000.xsl
32.19 real 28.49 user 0.42 sys
To see Saxon's optimizations, see the
RelationalExpression, PositionRange and
FilterEnumerator classes in com.icl.saxon.expr. We
could probably do something like this in 4XPath.