XPath descendant vs descendant-or-self Axis

In XML XPath navigation, the primary difference between the descendant axis and the descendant-or-self axis is the inclusion of the context node itself. While the descendant axis selects only the children, grandchildren, and further nested elements under the current node, the descendant-or-self axis evaluates both the current node and all of its nested sub-elements. Understanding this distinction is essential for writing accurate XPath expressions and avoiding unintended query results.

The descendant Axis

The descendant axis selects all elements that reside beneath the context node in the XML hierarchy, regardless of nesting depth. It includes children, grandchildren, great-grandchildren, and so on, but it strictly excludes the context node from the resulting node-set.

The descendant-or-self Axis

The descendant-or-self axis operates identically to the descendant axis, with one key addition: it includes the context node itself in the evaluation. If the context node matches the node test or condition specified, it will be included in the final result set alongside any matching nested elements.


Comparison with an XML Example

Consider the following XML document:

<section id="main">
    <div id="wrapper">
        <div id="nested">
            <p>Content</p>
        </div>
    </div>
</section>

If your context (current) node is <div id="wrapper">:

  1. descendant::div
    • Result: Returns <div id="nested">.
    • Explanation: Only the child div elements beneath the wrapper are selected. The context node itself is ignored.
  2. descendant-or-self::div
    • Result: Returns <div id="wrapper"> and <div id="nested">.
    • Explanation: Because the context node is a div, it matches the node test and is included along with the child div.

When to Use Each Axis