Testing within a Predicate by Using Boolean Operators
As a general rule, the predicate of a location step narrows the range of candidate nodes located by the step to just those that meet the condition specified by the predicate.
The result of such a condition is always a Boolean true or false value. Therefore, the complete syntax for predicates allows you to use a number of standard Boolean operators to compare two values. The table below summarizes these operators:
Operator | Description |
---|---|
= | If values to left and right of the "=" are equal, the result is true; otherwise the result is false. |
!= | If values to left and right of the "=" are not equal, the result is true; otherwise the result is false. |
< | If value to the left of the "<" is less than value to the right, the result is true; otherwise the result is false. |
> | If value to the left of the ">" is greater than value to the right, the result is true; otherwise the result is false. |
<= | If value to the left of the "<=" is less than or equal to value to the right, the result is true; otherwise the result is false. |
>= | If value to the left of the ">=" is greater than or equal to value to the right, the result is true; otherwise the result is false. |
test1 and test2 | If the results of both test1 and test2 are true, then the result of the test as a whole is true; otherwise the result is false. |
test1 or test2 | If the result of either test1 or test2 is true, then the result of the test as a whole is true; otherwise the result is false. |
A predicate must adhere to XML's rules for well-formed documents. Therefore, operators such as >, <, and &, which have special meaning to XML parsers, must be escaped using entity references such as >, <, and & respectively.
Example
This example is used to demonstrate the operators shown below.
XML File (book_qse.xml)
See Sample XML Data File for Boolean Operators in Predicates. This document represents a book, titled Quantum Superstring Electrodynamics for Newbies, which consists of two chapters. Each chapter contains two sections of text, intermingled with footnote references and pointers to illustrations; following the last <section>
element in each chapter is a list of the footnotes referred to in the text. Footnotes will be numbered sequentially from the beginning of the book to the end.
XSLT File (predicate.xsl)
See Sample XSLT File for Boolean Operators in Predicates.
Portions of this example style sheet which are relevant to the discussion of XPath predicates are reproduced below. The example style sheet includes many match and select patterns which could be replaced with more concise or efficient forms. Some of these patterns are also artificial, such as those which select for paragraphs beginning with certain letters of the alphabet. The style sheet's main purpose is to demonstrate various forms of XPath predicates, not to serve as an example of well-tuned XSLT code.
Formatted Output
See Sample Output for Boolean Operators in Predicates.
The = operator
Use an equals sign (=) in a predicate when you need to test whether one value exactly equals another. For instance:
<xsl:when test="parent::*[name()='chapter']
">
locates the parent of the context node only when that parent is named <chapter>
.
The != operator
Use the "not-equals" operator (!=) in a predicate when you need to test whether two values are not equal. For instance:
<xsl:template match="title[name(..)!='book']
">
locates a <title>
child of the context node only if that child's parent (that is, the context node itself) is not named <book>
.
Note The != operator can sometimes be used interchangeably with the XPath not()
function. For instance, these two predicates are interchangeable:
[name()!='book']
[not(name()='book')]
In such cases, which form of the test you use is a matter of taste. However, the two forms are not always identical—particularly when one of the values on either side of the operator is a node-set. For more information about the not()
function, see Testing an Expression by Using Boolean Functions.
The < operator
Use the less-than operator in a predicate when you need to test whether one value is less than another. For instance:
<xsl:template match="chapter[position()<2]
">
locates a <chapter>
child of the context node when that child is at an ordinal position less than 2 (i.e., when it is in the first position) among the current node-set.
The > operator
Use the greater-than operator in a predicate when you need to test whether one value is greater than another. For instance:
<xsl:template match="chapter[position()>1]
">
locates a <chapter>
child of the context node only if that child is greater than the first such child (that is, the second child, third child, and so on), in document order.
The <= operator
Use the less-than-or-equals operator in a predicate when you need to test whether one value is less than or equal to another. For instance:
<xsl:template match="@copyright[.<=2000]
">
locates all copyright
attributes with a value of 2000 or less.
The >= operator
Use the greater-than-or-equals operator in a predicate when you need to test whether one value is greater than or equal to another. For instance:
<xsl:template match="@copyright[.>=2001]
">
locates all copyright
attributes with a value of 2001 or greater.
The "and" operator
Use the and operator in a predicate when you need to perform more than one test in order to select from among candidate nodes. All of the tests joined by the and operator must be true in order for the selection to occur. For instance:
<xsl:template match="text[substring(.,1,1)!='T' and substring(.,1,1)!='B'
and substring(.,1,1)!='A' and substring(.,1,1)!='P']
">
This match pattern locates all <text>
elements which start with anything except the letters "T," "B," "A," or "P." <text>
elements beginning with any of those four letters will not be located.
The "or" operator
Use the or operator in a predicate when you need to perform any of several tests in order to select from among candidate nodes. Any of the tests joined by the or operator can be true in order for the selection to occur. For instance:
<xsl:template match="text[substring(.,1,1)='T' or substring(.,1,1)='B' or
substring(.,1,1)='A' or substring(.,1,1)='P']
">
This match pattern locates all <text>
elements which start with any of the letters "T," "B," "A," or "P." <text>
elements beginning with any other characters will not be located.