XPath Axes
An axis defines the direction of navigation from the current node in an XPath expression. The default direction is downward — selecting children. But XPath supports 13 axes that let you navigate in every direction through the tree: up to ancestors, sideways to siblings, forward to following nodes, and backward to preceding ones.
Think of axes like compass directions on a map. You stand at a specific location (the context node) and the axis tells you which direction to look — north, south, east, west — to find the nodes you want.
The 13 XPath Axes
| Axis Name | Direction / Nodes Selected |
|---|---|
| child | Direct children of the context node |
| parent | The single parent of the context node |
| self | The context node itself |
| ancestor | Parent, grandparent, and all ancestors up to root |
| ancestor-or-self | The context node plus all its ancestors |
| descendant | All children, grandchildren, and all below |
| descendant-or-self | The context node plus all its descendants |
| following-sibling | All siblings that come after the context node |
| preceding-sibling | All siblings that come before the context node |
| following | All nodes in the document after the context node's closing tag |
| preceding | All nodes in the document before the context node's opening tag |
| attribute | All attributes of the context node |
| namespace | All namespace nodes of the context node |
Axis Syntax
axis-name::node-test[predicate]
Working XML for Examples
<company>
<department id="D1" name="Engineering">
<team>Backend</team>
<team>Frontend</team>
<employee>
<name>Ravi Kumar</name>
<role>Developer</role>
</employee>
</department>
<department id="D2" name="HR">
<employee>
<name>Sunita Rao</name>
<role>Manager</role>
</employee>
</department>
</company>
Axis Navigation Diagram
ancestor
↑
preceding | following
←←←←← [context node: employee] →→→→→
|
descendant
↓
preceding-sibling ← [context: employee] → following-sibling
(same parent level)
child Axis
Selects direct children only. This is the default axis.
child::department → same as: department child::* → all child elements child::text() → all text node children child::employee → all employee children /company/child::department → both department elements
parent Axis
Selects the single parent node. Useful when you start at a deep node and need to go up one level.
/company/department/employee/parent::department
→ the department element that contains the employee
/company/department/team/parent::*
→ any parent element of team (the department)
ancestor Axis
Selects all ancestors — parent, grandparent, and above — up to and including the root.
/company/department/employee/name/ancestor::*
→ name, employee, department, company (all ancestors)
/company/department/employee/ancestor::department
→ the department ancestor of employee
/company/department/employee/ancestor::company
→ the company ancestor
descendant Axis
Selects all descendants at any depth below the context node.
/company/descendant::name
→ all name elements anywhere inside company
/company/department[1]/descendant::*
→ all elements inside the first department
/company/descendant::text()
→ all text content in the entire document
following-sibling and preceding-sibling Axes
Siblings share the same parent. These axes navigate sideways.
Assume context is the first <team> (Backend):
following-sibling::team
→ the Frontend team (comes after Backend)
following-sibling::employee
→ the employee element (comes after both teams)
preceding-sibling::*
→ all sibling elements before the current node
following and preceding Axes
These axes cover all nodes in document order after or before the context node — not just siblings, but nodes in completely different branches of the tree.
/company/department[1]/following::*
→ every element after the first department closes:
department[D2], employee[Sunita], name, role
/company/department[2]/preceding::*
→ every element before the second department opens:
department[D1], team[Backend], team[Frontend], employee[Ravi], name, role
attribute Axis
Selects the attributes of the context node. The @ shorthand is an abbreviation for attribute::.
/company/department/attribute::* → all attributes of all departments /company/department/attribute::id → the id attribute /company/department/attribute::name → the name attribute Abbreviated: /company/department/@* /company/department/@id
self Axis
Selects the context node itself. Useful in predicates to test the current node's own properties.
self::department → the context node if it is a department, otherwise nothing
self::* → the context node regardless of name
self::node() → same as self::*
Use case in a predicate:
//department[self::*[@id='D1']]
→ department that is itself named with id D1
Axis Examples in XSLT
<!-- Get the parent department name when processing an employee --> <xsl:template match="employee"> <p>Department: <xsl:value-of select="parent::department/@name"/></p> <p>Employee: <xsl:value-of select="name"/></p> </xsl:template> <!-- Count all following siblings --> <xsl:value-of select="count(following-sibling::employee)"/> <!-- List all ancestor element names --> <xsl:for-each select="ancestor::*"> <p><xsl:value-of select="name()"/></p> </xsl:for-each>
Key Points to Remember
- Axes define the direction of navigation from the current context node.
- child:: is the default axis — writing book is the same as child::book.
- ancestor:: goes up the tree; descendant:: goes down.
- following-sibling:: and preceding-sibling:: move sideways among shared-parent nodes.
- following:: and preceding:: cover all nodes in document order before or after the context node.
- attribute:: selects attributes — abbreviated as @.
- self:: selects the context node itself — useful in predicates and filtering.
