Location steps can be combined into location paths. A path optionally starts with a slash sign and continues with a sequence of at least one location step. Steps are separated by slash signs. A well-formed path is /descendant::L/child::*/child::*.
A path should be evaluated as follows. If the path starts with /, then the context node is set to the root node, otherwise a context node should be provides as input. The first step is evaluated at the context node resulting into a set of context nodes, called the context node set. Then, the second step is evaluated at each context node resulting from the evaluation of the first step. The resulting node sets are unioned to form the result of the second step. And so on. The result of the last step is also the result of the path. For instance, consider again the alphabet example:
The path /descendant::L/child::*/child::* selects the nodes labelled with O and P. Indeed, the root is the initial context node and the first step selects all root descendants labelled with L. The result contains only node L. The second step retrieves all children of L. These are nodes M, N, and Q. Finally, the third step selects all children of M, N, and Q and takes the union of the resulting sets. The result is nodes O and P.
Recall that a step has the form axis::test[filter], where [filter] is optional. Location paths may be used in filters of location steps. The filter part, as the name suggests, is used to filter the set of nodes selected by the path. The filtering process is as follows: the filter is applied to each node in the current set of nodes. If the result is not empty, then the node is left in the current node set, otherwise, the node is erased from the current node set. For instance, with reference to the alphabet example, the step /descendant::*[child::*] selects all internal nodes (nodes having at least one child): all root descendants are first selected and then the descendants having at least one child are left in the set. The result is colored in yellow:
As another example, the next step selects all nodes having at least two right siblings: /descendant::*[following-sibling::*/following-sibling::*]. The result is colored in yellow:
Location paths in filters can be combined with Boolean connectives and, or, and not. For instance, the path /descendant::*[not(child::*)] selects all leave nodes (nodes without children), the path /descendant::*[child::* and preceding-sibling::*] selects all internal nodes with at least one left sibling, and the path /descendant::*[ancestor::B or preceding::B] selects all nodes that follow B in the document order.