Finding a Particular Node

To find a specific node within a set of nodes, enclose an integer within brackets ( [ ] ). The integer indicates the position of the node relative to its parent. This section discusses the following topics:

See also Obtaining the Current Node for the Current XSLT Template.

About Node Positions

The node positions for a node set start with 1. Evaluation of the position number is always based on document order. For example, the following query returns the first author element in the current context:

author[1] 
               

            

The next query finds the author elements (in the current context) that contain a first-name element. The query returns the third such author element.

(author[first-name])[position()=3] 
               

            

When you specify an integer in brackets, it is equivalent to calling the position() function. For example, the following queries both return the third y child element of each x child element in the current context:

x/y[3]
               
x/y[position()=3]
               

            

Tip: If you do not know the position of the node you want, a call to the position() function might help you. See Determining the Position Number of a Node.

The return value of the position() function depends on the specified axis. For example, suppose the axis is one of the reverse axes, such as preceding, ancestor, or preceding-sibling. The position() function returns the nth one in reverse document order that falls in the specified axis.

Determining the Position Number of a Node

The position() function returns an integer that indicates the position of the node within the parent. Positions start with 1; a node with a position of 1 is always the first node in the collection.

For example, the following query returns the first three degree elements in the document:

(//degree)[position() < 4] 
               

            

The next query finds the first two book children in the current context:

book[position() <= 2] 
               

            

The XPath processor executes the position() function with respect to the parent node. Consider the following data:

<x>
               

              
<y/>
                   
<y/>
                   

                
</x> <x>
<y/>
                   
<y/>
                   

                
</x>

The following expression returns the first y element contained in each x element:

x/y[position() = 1] 
               

            

For more information, see also Finding an Element with a Particular ID.

Positions in Relation to Parent Nodes

Positions are relative to the parent. Consider the following data, which has line numbers on the left for explanation only.

1 	<x>
               
2 		<z>
               
3 		<z/>
               
4 	</x>
               
5 	<x>
               
6 		<y>
               
7 		<y/>
               
8	</x>
               
9	<x>
               
10		<y>
               
11		<y/>
               
12	</x>
               

            

The following query returns the first y element contained in each x element. It returns the elements on lines 6 and 10. The XPath processor finds all x elements. For each x element, the XPath processor then returns the first y element it finds.

x/y[1] 
               

            

The next query returns the first y element that is contained in an x element that is in the context node set. It returns the element on line 6. The XPath processor finds all y elements inside x elements. The XPath processor then returns the first element in that set.

(x/y)[1] 
               

            

The next query returns the empty set. The XPath processor finds the first x element. It then searches that first x element for the first y. Because the first x element does not contain a y element, this query returns the empty set.

x[1]/y[1] 
               

            

Finding Nodes Relative to the Last Node in a Set

To obtain nodes relative to the last node in the set, use the position() and last() functions with arithmetic. For example, the following queries both obtain the last author element in the current context:

author [position() = last()]
               
author [last()]
               

            

The following queries both return the next-to-last author element:

author [position() = last() - 1]
               
author [last() - 1]
               

            

For information about position(), see Determining the Position Number of a Node. For information about last(), see Determining the Context Size.

Finding Multiple Nodes

To obtain several nodes in one operation, use the and or the or operator with the position() and last() functions. For example, the following query returns the first and the last author nodes in the current context:

author [(position() = 1) or (position() = last())]
               

            

You can also specify a range of nodes. For example, the next query returns the second, third, and fourth author elements:

author [(position() >= 2) and ( position() <= 4)]
               

            

To obtain a range of nodes, m to n, relative to the last node, use the following format:

(m <= position()) and (position() <= n )

For example, the following query obtains the last five nodes in the current context:

author [(last() - 4) <= position()) and (position() <= last())]
               

            

Examples of Specifying Positions

The following query finds the first and fourth author elements:

author [(position() = 4) or (position() = 1)]
               

            

The next query finds the first, the third through the fifth, and the last author elements:

author [(position() = 1) or 
               

              
(position() >= 3 and position() <= 5) or 
                   
(position() = last())]
                   

                

The XPath processor removes duplicate values. For the previous query, if there are only five elements in the collection, the query returns only one copy of the fifth element.

The next example finds all author elements in which the first degree is a Ph.D.:

author[degree[1] = "Ph.D."] 
               

            

Finding the First Node That Meets a Condition

Suppose you want to obtain from a collection the first node that meets a certain condition. For example, you want the first book whose author's last name is Bob. You can specify the following query:

(//book[author/last-name="Bob"])[position()=1]
               

            

When the XPath processor evaluates this expression, it creates a collection of book elements where the author's last name is Bob. The XPath processor then returns the first node in this collection.

The following two expressions appear to also return the first book whose author's last name is Bob, but they do not. Instead, these queries both return a book whose author's last name is Bob only if that book is the first book in the document.

//book[author/first-name="Bob"][position()=1]
               
//book[author/first-name="Bob" and position() = 1]
               

            

Finding an Element with a Particular ID

To obtain the element that has a particular identifier (ID), the DTD must specify an attribute for that element. The type of this attribute must be ID. The name of the attribute is not significant, though it is typically id. If there is such an attribute, you can call the id() function to obtain the element with a particular ID. The format is

node-set  id(object) 
               

            

The id() function evaluates to a set. It ignores the context node set except to evaluate the function's argument. The result set contains an element node that has an attribute of type ID whose value is identical to the string the object argument evaluates to. The element node can appear anywhere in the document that is being queried.

For example:

id("special")
               

            

This query searches for an element that has an attribute whose

  • Type is ID
  • Value is special

Details about working with IDs are in the following topics:

The id() Function's Argument

When the id() function's argument is of type node-set, the result is the union of the results of applying id() to the string value of each of the nodes in the argument node set.

When the argument of id() is any other type, the XPath processor converts the argument to a string as if by a call to the string() function. The XPath processor splits the string into a white-space-separated list of tokens. The result is a node set that contains the elements in the same document as the context node that have a unique ID equal to any of the tokens in the list.

Unique IDs

An element node can have a unique ID. This is the value of the attribute that is declared in the DTD as type ID. No two elements in a document can have the same unique ID. If an XML processor reports two elements in a document as having the same unique ID (which is possible only if the document is invalid), the second element is treated as not having a unique ID.

If a document does not have a DTD, the id() function always returns an empty node list.

Obtaining Particular Types of Nodes By Using Node Tests

The node tests allow you to obtain nodes according to their type. Node test is an XPath term. Although a node test looks like a function, it is not a function.

You can use node tests with filters and position specifiers. They resolve to the set of children of the context node that meets the restrictions you specify.

Node tests for XPath 2.0 add to the set of node tests supported for XPath 1.0. Node tests common to both XPath 1.0 and XPath 2.0 are shown in Table 65. Node tests unique to XPath 2.0 are shown in Table 65.

Node Test
Node Type Returned
comment()
               

            
Comment nodes.
node()
               

            
All nonattribute nodes.
processing-
instruction("name") 
               

            
Processing instruction nodes. The processing-instruction() node test selects all processing instructions. When this node test specifies a literal argument, it selects any processing instruction that has a name equal to the value of the argument. If there is no argument, this node test selects all processing instructions.
text()
               

            
Text nodes and CDATA nodes.
Table 65. Node Test Return Values Common to XPath 1.0 and XPath 2.0

Node Test
Node Type Returned
attribute()
               

            
Matches any attribute node.
document-node()
               

            
Matches any document node.
element()
               

            
Matches any element node.
item()
               

            
Matches any single item.
Table 66. Node Test Return Values Unique to XPath 2.0

For each p element in the current context, the following query returns its second text child node:

p/text()[2] 
               

            

Following is a query that finds the third comment child in each foo element anywhere in the document:

//foo/comment()[3]
               

            

About the Document Object

In the Document Object Model (DOM), a document contains comments, processing instructions, and declarations, as well as the document element. As in XPath, the root node is the root of the DOM tree, and the root node is not the same as the document element. This allows comments, declarations, and processing instructions at the document entity level.

For example, the following query finds all comments at the document entity level. In other words, it finds all comments that are immediate children of the root node.

/comment() 
               

            

This query returns the comment at the beginning of the bookstore.xml file:

"This file represents a fragment of a book store inventory database."

Getting Nodes of a Particular Type

A query like the following returns all the comments in a document:

//comment()
               

            

The following query returns the third comment in the document.

(//comment()) [3] 
               

            

 
Free Stylus Studio XML Training: