Reputation: 2807
consider (hand written code so excuse any accidents)
<xsl:variable name="foo" as="document-node()">
<xsl:document>
<foo1>
<foo2>
<foo3>
</xsl:document>
</xsl:variable>
<xsl:variable name="foos" select="$foo/*"/>
<xsl:variable name="isItFoo3" select="$foos[2]::following-sibling"/>
and isItFoo3 is <foo3>
nice
but this
<xsl:variable name="foos" as="element()*">
<foo1>
<foo2>
<foo3>
</xsl:variable>
<xsl:variable name="isItFoo3" select="$foos[2]::following-sibling"/>
results in empty
so, I'm assuming that following sibling requires a parent (by definition!) and literal elements in my 2nd example are orphaned in some sense, so they arent siblings.
This makes axes a little subtle, if I want to process (effectively get the 'tail') of a sequence, I need to ensure that all elements have a parent and share the same parent.
fair enough, that makes logical sense.
but then how do I get the tail (following-siblings) in a sequence when I'm not sure of the parentage of the elements?
(ok, I can explicitly copy them into a new document to make sure, but thats a little onerous, in terms of code and performance)
Upvotes: 0
Views: 33
Reputation: 167716
So you can do e.g.
<?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">
<xsl:variable name="foos" as="element()*">
<foo1/>
<foo2/>
<foo3/>
<foo4/>
</xsl:variable>
<xsl:variable name="foo2" select="$foos[2]"/>
<xsl:variable name="foos-after-foo2" select="let $pos := index-of($foos!generate-id(), generate-id($foo2)) return $foos[position() gt $pos]"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/" name="xsl:initial-template">
<xsl:sequence select="$foos-after-foo2"/>
</xsl:template>
</xsl:stylesheet>
I think it can be expressed more compactly in XPath/XSLT 4, currently (still work in progress, I use XQuery syntax for the variable assignment)
let $foos := (<foo1/>, <foo2/>, <foo3/>, <foo4/>),
$foo2 := $foos[2],
$pos := index-where($foos, fn { . is $foo2 })
return $foos[position() gt $pos]
or as
let $foos := (<foo1/>, <foo2/>, <foo3/>, <foo4/>),
$foo2 := $foos[2]
return subsequence($foos, index-where($foos, fn { . is $foo2 }) + 1)
Upvotes: 0