Stylus Studio XML Editor

Table of contents

Appendices

5.2 Patterns

Patterns

Template rules identify the nodes to which they apply by using a pattern. As well as being used in template rules, patterns are used for numbering (see [Numbering]) and for declaring keys (see [Keys]). A pattern specifies a set of conditions on a node. A node that satisfies the conditions matches the pattern; a node that does not satisfy the conditions does not match the pattern. The syntax for patterns is a subset of the syntax for expressions. In particular, location paths that meet certain restrictions can be used as patterns. An expression that is also a pattern always evaluates to an object of type node-set. A node matches a pattern if the node is a member of the result of evaluating the pattern as an expression with respect to some possible context; the possible contexts are those whose context node is the node being matched or one of its ancestors.

Here are some examples of patterns:

  • para matches any para element

  • * matches any element

  • chapter|appendix matches any chapter element and any appendix element

  • olist/item matches any item element with an olist parent

  • appendix//para matches any para element with an appendix ancestor element

  • / matches the root node

  • text() matches any text node

  • processing-instruction() matches any processing instruction

  • node() matches any node other than an attribute node and the root node

  • id("W11") matches the element with unique ID W11

  • para[1] matches any para element that is the first para child element of its parent

  • *[position()=1 and self::para] matches any para element that is the first child element of its parent

  • para[last()=1] matches any para element that is the only para child element of its parent

  • items/item[position()>1] matches any item element that has a items parent and that is not the first item child of its parent

  • item[position() mod 2 = 1] would be true for any item element that is an odd-numbered item child of its parent.

  • div[@class="appendix"]//p matches any p element with a div ancestor element that has a class attribute with value appendix

  • @class matches any class attribute (not any element that has a class attribute)

  • @* matches any attribute

A pattern must match the grammar for Pattern. A Pattern is a set of location path patterns separated by |. A location path pattern is a location path whose steps all use only the child or attribute axes. Although patterns must not use the descendant-or-self axis, patterns may use the // operator as well as the / operator. Location path patterns can also start with an id or key function call with a literal argument. Predicates in a pattern can use arbitrary expressions just like predicates in a location path.

Patterns
5.2    Pattern   ::=   LocationPathPattern
| Pattern '|' LocationPathPattern
5.2    LocationPathPattern   ::=   '/' RelativePathPattern?
| IdKeyPattern (('/' | '//') RelativePathPattern)?
| '//'? RelativePathPattern
5.2    IdKeyPattern   ::=   'id' '(' Literal ')'
| 'key' '(' Literal ',' Literal ')'
5.2    RelativePathPattern   ::=   StepPattern
| RelativePathPattern '/' StepPattern
| RelativePathPattern '//' StepPattern
5.2    StepPattern   ::=    ChildOrAttributeAxisSpecifier NodeTest Predicate*
5.2    ChildOrAttributeAxisSpecifier   ::=   AbbreviatedAxisSpecifier
| ('child' | 'attribute') '::'

A pattern is defined to match a node if and only if there is possible context such that when the pattern is evaluated as an expression with that context, the node is a member of the resulting node-set. When a node is being matched, the possible contexts have a context node that is the node being matched or any ancestor of that node, and a context node list containing just the context node.

For example, p matches any p element, because for any p if the expression p is evaluated with the parent of the p element as context the resulting node-set will contain that p element as one of its members.

NOTE: 

This matches even a p element that is the document element, since the document root is the parent of the document element.

Although the semantics of patterns are specified indirectly in terms of expression evaluation, it is easy to understand the meaning of a pattern directly without thinking in terms of expression evaluation. In a pattern, | indicates alternatives; a pattern with one or more | separated alternatives matches if any one of the alternative matches. A pattern that consists of a sequence of StepPatterns separated by / or // is matched from right to left. The pattern only matches if the rightmost StepPattern matches and a suitable element matches the rest of the pattern; if the separator is / then only the parent is a suitable element; if the separator is //, then any ancestor is a suitable element. A StepPattern that uses the child axis matches if the NodeTest is true for the node and the node is not an attribute node. A StepPattern that uses the attribute axis matches if the NodeTest is true for the node and the node is an attribute node. When [] is present, then the first PredicateExpr in a StepPattern is evaluated with the node being matched as the context node and the siblings of the context node that match the NodeTest as the context node list, unless the node being matched is an attribute node, in which case the context node list is all the attributes that have the same parent as the attribute being matched and that match the NameTest.

For example

appendix//ulist/item[position()=1]

matches a node if and only if all of the following are true:

  • the NodeTest item is true for the node and the node is not an attribute; in other words the node is an item element

  • evaluating the PredicateExpr position()=1 with the node as context node and the siblings of the node that are item elements as the context node list yields true

  • the node has a parent that matches appendix//ulist; this will be true if the parent is a ulist element that has an appendix ancestor element.