Re: [xsl] Best Way to Select Following Elements With An Ancestor?

Subject: Re: [xsl] Best Way to Select Following Elements With An Ancestor?
From: Michael Kay <mike@xxxxxxxxxxxx>
Date: Sat, 22 Mar 2014 15:18:21 +0000
> well if you know there's a dita acestor,
>
> count(ancestor::dita | $myDitaAncestor) = 1
>
> can be written
>
> ancestor::dita is $myDitaAncestor
>


I think you'll be very lucky if you find a processor that optimizes

following::*[ancestor::dita is $myDitaAncestor]

to only search the subtree of $myDitaAncestor. If this subtree is a small part
of the whole, then the expression is going to be pretty inefficient.

In general I suspect

$myDitaAncestor//*[. >> current()]

is likely to be better (it's not exactly equivalent of course because it will
also select ancestors of current()).

Probably the most efficient is to search following nodes until you reach one
that does not have the right ancestor, and then stop. This would be

<xsl:function name="following-in-subtree" as="element()*">
  <xsl:param name="this"/>
  <xsl:param name="ditaAncestor"/>
  <xsl:sequence select="
    if ($this/ancestor::* intersect $ditaAncestor)
    then ($this, following-in-subtree($this/following::*[1], $ditaAncestor))
    else ()"/>
</xsl:function>

(This relies on a conjecture about the following axis which I'm too lazy to
prove just now: that if A is on the following axis starting from B, then
A/following::* is a trailing subsequence of B/following::*)

Michael Kay
Saxonica

Current Thread