1. Overview

In this tutorial, we're going to look at selecting sibling nodes.

The sibling axes include preceding-sibling:: and following-sibling::. As the names suggest, the preceding-sibling axis consists of siblings that precede the context node and the following-sibling axis consists of siblings that follow it. Siblings are, of course, child nodes that share the same parent.

2. Sample Input

Let's continue with our sample XML input:

<Records>
    <A id="1"/>
    <A id="2"/>
    <B id="3"/>
    <A id="4"/>
    <B id="5"/>
    <C id="6"/>
    <A id="7"/>
    <A id="8"/>
    <B id="9"/>
</Records>

 

3. Transformation Examples

Now, we'll list several examples to illustrate the sibling-based selection.

First of all, /Records/A[4]/ is the context node, thus we'll perform selections relative to this element.

We will evaluate the example statements according to this assumption. Nonetheless, we will also include it in XPath expressions to represent the full location.

> Select all A sibling elements that precede the context node.

/Records/A[4]/preceding-sibling::A

Result:

<A id="1"/>
<A id="2"/>
<A id="4"/>

 

> Select all A sibling elements that follow the context node.

/Records/A[4]/following-sibling::A

Result:

<A id="8"/>

 

> Select all sibling elements that precede the context node.

/Records/A[4]/preceding-sibling::*

Result:

<A id="1"/>
<A id="2"/>
<B id="3"/>
<A id="4"/>
<B id="5"/>
<C id="6"/>

 

> Select the first preceding sibling element named A in reverse document order.

/Records/A[4]/preceding-sibling::A[1]

Result:

<A id="4"/>

 

> Select the first preceding element in reverse document order, provided it is an A.

/Records/A[4]/preceding-sibling::*[1][self::A]

Result:

No Match!

 

> Select the first preceding element in reverse document order, provided it is a C.

/Records/A[4]/preceding-sibling::*[1][self::C]

Result:

<C id="6"/>

 

> Select all preceding sibling elements that are not A elements

/Records/A[4]/preceding-sibling::*[not(self::A)]

Result:

<B id="3"/>
<B id="5"/>
<C id="6"/>

 

> Select the element directly preceding the context node provided it has a child element A.

/Records/A[4]/preceding-sibling::*[1][A]

Result:

No Match!