We have more to tell before we present "Location Steps in Summary," a later section that concisely explains what location steps do. For now, let's look at some more examples.
As mentioned, /Insured/CarPolicy/Vehicle makes available all Vehicle nodes that are children of any CarPolicy child within Insured . The following expression resolves to the node whose string value is Buick .
/Insured/CarPolicy/Vehicle[@Category='Coupe']/Make
In contrast,
/Insured/CarPolicy[1]/Vehicle
is more
/Insured/CarPolicy[1]/Vehicle[@Category='Coupe']/Make
/Insured/CarPolicy[last()] selects (within Insured ) the last CarPolicy node, which is the node whose PolicyType attribute has the string value Antique .
/Insured/CarPolicy[last()]/Vehicle[last()] selects the third Vehicle node within the second CarPolicy node. That Vehicle node has details on the Porsche Speedster .
Let's talk about the returned nodes whose string values are not available to you. The following expression resolves to a set of two Make nodes (one for Ford , one for Buick ).
/Insured/CarPolicy/Vehicle[2]/Make
Only the first Make node seems to be available. The reason is that most XPath processors (such as the ones used with BPEL) provide the string value only of the first returned node.
The following expression returns an empty set.
/Insured/CarPolicy/Vehicle[2]/Make[2]
The set is empty because each of the two Vehicle nodes selected by /Insured/CarPolicy/Vehicle[2] has only one Make child, and the predicate [2] refers not to the whole expression but to the Make node.
How do you access only the
Make
node that refers to
Buick
? The solution is to use parentheses, which selects a node set that can be filtered by a predicate. In the
(/Insured/CarPolicy/Vehicle[2]/Make)[2]
Incidentally, a parenthetical expression is valid only at the beginning of a location
<!- not a valid expression with XPath 1.0 -> /Insured/CarPolicy/(Vehicle)
Now, let's look again at the effect of the last() function. The following expression returns, for each CarPolicy node, the Make child of the second Vehicle element:
{% if main.adsdop %}{% include 'adsenceinline.tpl' %}{% endif %}
/Insured/CarPolicy/Vehicle[2]/Make[last()]
The value of last() is 1 , and although the XPath processor returns two nodes (one for Ford , one for Buick ), the only returned string value is Ford .
The following expression returns the last
Make
node of the nodes returned from the
(/Insured/CarPolicy/Vehicle[2]/Make)[last()]
The value of
last()
is
2
, and the
A predicate operates in the context of the previous location steps and the syntax that precedes the predicate in the same location step. Therefore … what is the result of the next expression?
/Insured/CarPolicy/Vehicle[@Category='Sport'][2]/Make
This expression
Subordinate to the first CarPolicy node is a node set that contains all Vehicle nodes whose Category attribute equals Sport . One node is present, and its Make child has the string value Ford . When applied to this set, the predicate [2] yields an empty set.
Subordinate to the second CarPolicy node is a node set that also contains all Vehicle nodes whose Category attribute equals Sport . Two nodes are present, and their Make children have the respective string values Triumph and Porsche . When applied to this set, the predicate [2] yields the second node.
Here's a variation:
/Insured/CarPolicy/Vehicle[@Category='Sport'][last()]/Make
Each of the branches mentioned earlier now
Order counts, even within a location step. The next example returns the Make node for the second Vehicle child within each CarPolicy node, with the further restriction that the value of attribute Category is Sport :
/Insured/CarPolicy/Vehicle[2][@Category='Sport']/Make
The string value of the single returned node is Ford .