home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam    

Book HomeXML in a NutshellSearch this book

9.4. Predicates

In general, an XPath expression may refer to more than one node. Sometimes this is what you want, but sometimes you want to further winnow the node-set. You want to select only some of the nodes the expression returns. Each step in a location path may (but does not have to) have a predicate that selects from the node list current at that step in the expression. The predicate contains a Boolean expression, which is tested for each node in the context node list. If the expression is false, then that node is deleted from the list. Otherwise, it's retained.

For example, suppose you want to find all profession elements whose value is "physicist." The XPath expression //profession[. = "physicist"] does this. Here the period stands for the string value of the current node, the same as would be returned by xsl:value-of. You can use single quotes around the string instead of double quotes, which is often useful when the XPath expression appears inside a double-quoted attribute value, for example, <xsl:apply-templates select="//profession[.= 'physicist']" />.

If you want to ask for all person elements that have a profession child element with the value "physicist," you'd use the XPath expression //person[profession="physicist"]. If you want to find the person element with id p4567, put an @ in front of the name of the attribute as in //person[@id="p4567"].

As well as the equals sign, XPath supports a full complement of relational operators including <, >, >=, <=, and !=. For instance, the expression //person[@born<=1976] locates all person elements in the document with a born attribute whose numeric value is less than or equal to 1976. Note that if this expression is used inside an XML document, you still have to escape the less-than sign as &lt;, for example, <xsl:apply-templates select="//person[@born &lt;= 1976]"/>. XPath doesn't get any special exemptions from the normal well-formedness rules of XML. On the other hand, if the XPath expression appears outside of an XML document, as it may in some uses of XPointer, then you may not need to escape the less-than sign.

XPath also provides Boolean and and or operators to combine expressions logically. For example, the XPath expression //person[@born<=1920 and @born>=1910] selects all person elements with born attribute values between 1910 and 1920 inclusive. //name[first_name="Richard" or first_name="Dick"] selects all name elements that have a first_name child with the value of either Richard or Dick.

In some cases the predicate may not be a Boolean, but it can be converted to one in a straightforward fashion. Predicates that evaluate to numbers are true if they're equal to the position of the context node, otherwise false. Predicates that indicate node-sets are true if the node-set is nonempty and false if it's empty. String values are true if the string isn't the empty string, false if it is. For example, suppose you want to select only those name elements in the document that have a middle_initial child element. The XPath expression //name selects all name elements. The XPath expression //name[middle_initial] selects all name elements and then checks each one to see if it has a middle_initial child element. Only those that do are retained. When applied to Example 9-1, this expression indicates Richard P. Feynman's name element but not Alan Turing's.

Any or all of the location steps in a location path can have predicates. For example, the XPath expression /people/person[@born < 1950]/name[first_name = "Alan"] first selects all people child elements of the root element (of which there's exactly one in Example 9-1). Then from those it chooses all person elements whose born attribute has a value numerically less than 1950. Finally, from that group of elements, it selects all name child elements that have a first_name child element with the value "Alan."

Library Navigation Links

Copyright © 2002 O'Reilly & Associates. All rights reserved.