Discussion:
[Xpath] Finding the *first* preceding sibling
Stephane Bortzmeyer
2003-04-04 14:26:45 UTC
Permalink
I try to extract a text if the *immediate* preceding sibling is a
given element (here, <blink>).

For instance, in this document:

<?xml version="1.0" ?>
<para>Foo <blink>bar</blink> baz <invisible>bol</invisible>end.</para>

The Xpath expression '/para/node()[preceding-sibling::blink]' yields:

Found 3 nodes in simple.xml:
-- NODE --
baz
-- NODE --
<invisible>bol</invisible>
-- NODE --
end.

which seems fine. But I would like to retrieve only the node with
content "baz". I tried '/para/node()[preceding-sibling::blink[1]]' but
it gives exactly the same set of nodes.

What did I miss in the Xpath specification?

XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
David Carlisle
2003-04-04 14:47:48 UTC
Permalink
Post by Stephane Bortzmeyer
What did I miss in the Xpath specification?
That the steps are read left to right.

preceding-sibling::blink

selects all the preceding-sibling blink nodes so

preceding-sibling::blink[1]

selects the first of those.

So this set is non empty (so true in a boolean test) in exactly the same
cases as

preceding-sibling::blink

namely if there is a preceding-sibling blink node.

You want to find the immediately preceding node

preceding-sibling::node()[1]

then test if it is a blink


preceding-sibling::node()[1][self::blink]

David

________________________________________________________________________
This e-mail has been scanned for all viruses by Star Internet. The
service is powered by MessageLabs. For more information on a proactive
anti-virus service working around the clock, around the globe, visit:
http://www.star.net.uk
________________________________________________________________________

XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Michael Kay
2003-04-04 15:20:29 UTC
Permalink
I tried
'/para/node()[preceding-sibling::blink[1]]' but it gives
exactly the same set of nodes.
What did I miss in the Xpath specification?
If a node has a preceding sibling called "blink", then one of these will
be the first, so the two conditions are equivalent.

You want to test whether the first preceding sibling is called "blink":

[preceding-sibling::*[1][self::blink]]

Michael Kay
Software AG
home: ***@ntlworld.com
work: ***@softwareag.com


XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Continue reading on narkive:
Loading...