[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

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 17:44:04 +0000

On 22 Mar 2014, at 17:16, David Rudel <fwqhgads@xxxxxxxxx> wrote:

> On Sat, Mar 22, 2014 at 1:46 PM, Eliot Kimber <ekimber@xxxxxxxxxxxx> wrote:
>> I have a document where each child of the root element establishes a
>> unique content with regard to the output result (in this case,
>> corresponding to InDesign frames).
>>
>> For a given descendant of one of these elements I need to know if there
>> are any following elements within the same context.

Yes, that's what Eliot wrote, though his code snippet suggested he was
interested not only in knowing whether or not such a node exists, but also in
grabbing it.

However, even if you want the next following node that is a descendant of D,
as some of us assumed, your approach appears useful.

I believe it is true (though I have great trouble proving such things
rigorously) that $A/following::* is equivalent to
$A/ancestor-or-self::*/following-sibling::*/descendant-or-self::*.

It then follows that $A/following::*[ancestor::* intersect $D] can be
rewritten as $A/ancestor-or-self::*[ancestor::* intersect
$D]/following-sibling::*/descendant-or-self::*, since if $X has $D as an
ancestor, then every node in $X/following-sibling::*/descendant-or-self::*
also has $D as an ancestor.

Michael Kay

>
> I may be thinking about this the wrong way, but it seems like the
> situation you describe (some following element exists that is a
> descendant of the same context-setting node) is equivalent to saying
> "Either this node has a following-sibling, or some ancestor of it has
> a following-sibling, not counting the context-setting nodes."
>
> Is the above accurate?
>
> If the above understanding is correct, then a more elegant answer
> would be to use recursive functions:
>
> Define a recursive function that uses the following logic:
> f($x) = false if $x is one of the context nodes (/child::element())
> f($x) = true if $x has any following::sibling elements.
> f($x) = f($x/..) if neither of the above statements resolves the answer.
>
> Or, without recursive functions:
>
> Define a variable containing the context-setting nodes:
> $context_nodes = /child::element()
>
> Then the predicate you want is:
>
>
boolean(ancestor-or-self::element()[not($context_nodes)]/following-sibling::e
lement()
>
> -David
>
> --
>
> "A false conclusion, once arrived at and widely accepted is not
> dislodged easily, and the less it is understood, the more tenaciously
> it is held." - Cantor's Law of Preservation of Ignorance.


Current Thread