Navigating Input Documents Using Paths - Node Tests (Page 3 of 4 )
In addition to having an axis, each axis step has a node test. The node test indicates which of the nodes (by name or node kind) to select, along the specified axis. For example, child::product only selects product element children of the context node. It does not select other kinds of children (for example, text nodes), or other product elements that are not children of the context node.
Node name tests
In previous examples, most of the node tests were based on names, such as product and dept. These are known as name tests. The syntax of a node name test is shown in Figure 4-2.
Figure 4-2.Syntax of a node name test
Node name tests and namespaces
Names used in node tests are qualified names, meaning that they are affected by namespace declarations. A namespace declaration is in scope if it appears in an outer element, or in the query prolog. The names may be prefixed or unprefixed. If a name is prefixed, its prefix must be mapped to a namespace using a namespace declaration.
If an element name is unprefixed, and there is an in-scope default namespace declared, it is considered to be in that namespace; otherwise, it is in no namespace. Attribute names, on the other hand, are not affected by default namespace declarations.
Use of namespace prefixes in path expressions is depicted in Example 4-1, where the prod prefix is first mapped to the namespace, and then used in the steps prod:product and prod:number. Keep in mind that the prefix is just serving as a proxy for the namespace name. It is not important that the prefixes in the path expressions match the prefixes in the input document; it is only important that the prefixes map to the same namespace. In Example 4-1, you could use the prefix pr instead of prod in the query, as long as you used it consistently throughout the query.
You can use wildcards to match names. The step child::* (abbreviated simply *) can be used to select all element children, regardless of name. Likewise, @* (or attribute::*) can be used to select all attributes, regardless of name.
In addition, wildcards can be used for just the namespace and/or local part of a name. The step prod:* selects all child elements in the namespace mapped to the prefix prod, and the step *:product selects all product child elements that are in any namespace, or no namespace.
Node kind tests
In addition to the tests based on node name, you can test based on node kind. The syntax of a node kind test is shown in Figure 4-3.
Figure 4-3.Syntax of a node kind testa
The test node() will retrieve all different kinds of nodes. You can specify node() as the entire step, and it will default to the child:: axis. In this case, it will bring back child element, text, comment, and processing-instruction nodes (but not attributes, because they are not considered children). This is in contrast to *, which selects child element nodes only.
You can also use node() in conjunction with the axes. For example, ancestor::node() returns all ancestor element nodes and the document node (if it exists). This is different from ancestor::*, which returns ancestor element nodes only. You can even use attribute::node(), which will return attribute nodes, but this is not often used because it means the same as @*.
Four other kind tests, text(), comment(), processing-instruction(), and document-node(), are discussed in Chapter 21.
If you are using schemas, you can also test elements and attributes based on their type using node kind tests. For example, you can specify element(*, ProductType) to return all elements whose type is ProductType, or element(product, ProductType) to return all elements named product whose type is ProductType. This is discussed further in the section "Sequence Types and Schemas" in Chapter 13.