child::Direct children (default axis)
The child axis selects all immediate children of the context node. It's the default axis, so writing child::book is equivalent to just writing book. You rarely need to spell it out, but it helps clarify intent in complex expressions or when teaching how axes work.
Example: child::book
parent::Parent node
The parent axis selects the single element that directly contains the context node. It's the inverse of child and is useful when you've matched something deep in the tree and need to navigate one level up — for example, finding which element contains a particular text node.
Example: parent::catalog
ancestor::All ancestors up to root
The ancestor axis selects every element above the current node in the document tree, all the way up to the root. This is useful when you've matched a deeply nested node and need to find the containing structure — for example, finding which recipe contains a specific ingredient.
Example: ancestor::section
ancestor-or-self::Ancestors including self
Like ancestor, but the result set also includes the context node itself. This is handy when you need to check whether the current node or any of its ancestors matches a condition — for example, testing if you're inside a particular container.
Example: ancestor-or-self::div
descendant::All descendants
The descendant axis selects every node below the context node — children, grandchildren, and so on. It's a deep search. The shorthand // is actually descendant-or-self::node()/, so descendant:: without 'or-self' is slightly more precise when you know you don't want the context node in the result.
Example: descendant::item
descendant-or-self::Descendants including self
Selects the context node plus all of its descendants. The // shorthand in XPath is actually an abbreviation for /descendant-or-self::node()/, making this one of the most commonly used axes even if you don't write it out explicitly.
Example: descendant-or-self::*
following::Everything after closing tag
The following axis selects every node in the document that comes after the context node's closing tag, excluding descendants. It traverses the document in reading order. This is useful for finding content that appears later in the document regardless of nesting level.
Example: following::chapter
following-sibling::Siblings after current node
Selects only the siblings (same parent) that come after the context node in document order. Unlike following::, this stays within the same parent element. It's perfect for navigating sequential items like list entries or steps that follow the current one.
Example: following-sibling::p
preceding::Everything before opening tag
The preceding axis selects every node that appears before the context node's opening tag in document order, excluding ancestors. It's the mirror of following:: and is useful for finding content that appeared earlier in the document.
Example: preceding::title
preceding-sibling::Siblings before current node
Selects siblings (same parent) that come before the context node. This is handy for looking backward among peers — for example, finding all steps that come before the current step, or checking previous items in a list.
Example: preceding-sibling::li
self::The current node
The self axis contains only the context node itself. While it might seem redundant, it's useful for type-checking: self::ingredient tests whether the current node is an <ingredient> element, acting as a filter without moving to a different node.
Example: self::node()
attribute::Attributes (shorthand: @)
The attribute axis selects the attributes of the context node. In practice, you almost always use the @ shorthand instead — @id is equivalent to attribute::id. Attributes are not child nodes in XPath's data model, so you need this axis (or @) to access them.
Example: @id
namespace::Namespace nodes
The namespace axis selects the namespace nodes of the context element. Each in-scope namespace declaration is represented as a namespace node. This axis is rarely used in everyday XPath but is important when working with documents that use multiple XML namespaces.
Example: namespace::*