XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition (487 page)

BOOK: XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition
10.19Mb size Format: txt, pdf, ePub

An Algorithm for Matching Patterns

This means there is a theoretical algorithm for testing whether a given node
N
matches a pattern
P
, as follows: for each node, starting from
N
and working through its ancestors up to the root node, evaluate
P
as an XPath expression with that node as the context node. If the result is a sequence of nodes containing
N
, the pattern matches; otherwise, keep trying until you get to the root.

XSLT processors don't usually use this algorithm, it's there only as a way of stating the formal rules. The processor will usually be able to find a faster way of doing the test—which is just as well, since pattern matching would otherwise be prohibitively expensive.

Although the formal rules usually give the answer you would expect intuitively, there can be surprises. For example, you might expect the pattern
node()
to match any node; but it doesn't. The equivalent expression,
//(node())
is short for
root(.)/descendant-or-self::node()/child:: node()
, and the only nodes that this can select are nodes that are children of something. Because document nodes, attribute nodes, and namespace nodes are never children of another node (see the description of the tree model on page 45 in Chapter 2), they will never be matched by the pattern
node()
.

Patterns Containing Predicates

The formal equivalence of patterns and expressions becomes critical when considering the meaning of predicates (conditions in square brackets), especially predicates that explicitly or implicitly use the
position()
and
last()
functions.

For example, the pattern
para[1]
corresponds to the expression
root(.)//(para [position() = 1])
. This expression takes all the

children of the context node, and then filters this sequence to remove all but the first (in document order). So the pattern
para[1]
matches any

element that is the first

child of its parent. Similarly, the pattern
*[1][self::para]
matches any element that is the first child of its parent and that is also a

element, while
para[last()! = 1]
matches any

element that is a child of an element with two or more

children.

Other books

Russian Killer's Baby by Bella Rose
News of a Kidnapping by Gabriel García Márquez, Edith Grossman
All Light Will Fall by Almney King
Aidan by Sydney Landon
The Summer Cottage by Lily Everett
Emma Who Saved My Life by Wilton Barnhardt
Giant's Bread by Christie, writing as Mary Westmacott, Agatha