9.6. XPath Functions
In addition to what we have seen so far, XPath provides functions that either operate on or return one of the following four data types:
9.6.1. Boolean Functions
XPath has four Boolean functions: TRue(), false(), not(), and boolean(). The functions TRue() and false() return exactly what you would expect, true or false. The not() takes the Boolean value passed and returns the opposite. This provides yet another roundabout method to find the book Way Station:
//book[@publisher = 'Del Rey' and not(series = 'The Lord of the Rings')]
The boolean() function operates a little differently; it takes the argument and evaluates it, returning either true or false. If the event of the argument is a node set, only the first node is evaluated; the rest are ignored. Omitting the argument results in the current context node (.) being evaluated, with either TRue or false being returned.
9.6.2. Numeric Functions
Six numeric functions exist: ceiling(), count(), floor(), round(), number(), and sum(). Each of the first three functions accepts a single argument and acts upon that single argument. The ceiling() function returns the smallest integer that is greater than or equal to the argument. The function count() returns the number of nodes in the argument node set. The floor() function returns the largest integer that is less than or equal to the argument passed. The function round() returns the integer closest to the argument; if the number is equidistant between two integers, the largest is returned. The number() function evaluates the argument, or context node, and returns either the numeric value of the node or NaN (Not a Number). The function sum() operates upon the passed node set, first working like the number() function and then adding together the individual values and returning the sum.
9.6.3. Node Set Functions
XPath provides five node set functions: last(), position(), local-name(), name(), and namespace-uri(). The last() function returns the number that corresponds to the last node in a node set. For example, this is the XPath statement to find the last book:
The position() function returns the number that corresponds to the context node. This provides an alternate method of retrieving the same result as the last() function by coding either of the following two statements:
//book[position() = last()] //book[position() = 8]
The local-name() function returns the part of a node name following the colon (:). If there is no colon, the function works like the name() function, returning the full node name for either the argument or the context node. The namespace-uri() function returns the URI used in a namespace declaration, which is the value of the xmlns or xmlns: attribute.
9.6.4. String Functions
XPath provides a plethora of string functions that can be used either singly or in combination with one another to produce the desired results. These functions are concat(), contains(), normalize-space(), starts-with(), stringlength(), substring(), substring-after(), substring-before(), and translate().
The concat() function converts each of the arguments to strings, concatenates them, and then returns the result. The arguments can be literals, nodes, or node sets. However, with node sets, only the first node is evaluated. For example, this produces the string "Clifford D. Simak, Way Station":
concat(//author, ', ', //title)
The function contains() is used to test a string to determine whether it contains another string as a substring. This can be useful when only partial information is availablefor example, if you're looking for a book with "Lord" in the title:
The normalize-space() function removes leading and trailing whitespace from a string; in addition, any multioccurrence of whitespace is replaced with a single space. So the string "Post no bills!" becomes "Post no bills!".
The starts-with() function operates in the same manner as the contains() function, with the sole exception that only the beginning of a string is tested. So unless the string begins with the substring, the result is false.
The string-length() function returns the length of the string argument passed, which is particularly useful when testing for elements with or without contents. For example, to test for books that are not part of any series, the following XPath statement could be used:
//book[string-length(series) = 0]
The next three functions all relate to returning a substring of a string. The substring(), substring-after() and substring-before() functions each return a substring of the string argument. The substring() function has the following two formats:
substring(string, start) substring(string, start, length)
Using the XML document from Listing 9-1, the result of the following XPath would be Station:
By specifying the substring function's length argument in the following manner, the result would be Stat:
Of course, there is an easier way to get the Station results. The substring-after() function returns the entire substring immediately following the specified argument substring. Using the substring-after() function, it is not necessary to know that the second word starts in position 5; all that is necessary is knowing that it follows a space, as shown in the following example:
The third substring function is substring-before(), which returns the entire substring immediately before the argument string.
The final string function is translate(), which substitutes characters in the first string argument based upon the characters in the second and third strings. This is the basic format:
Translate(string, from-string, to-string)
The capabilities of this function lead to several interesting possibilities. For example, let's say that it is necessary to convert a string, such as the author of the third book, to all upper case. This can be accomplished by using the following XPath:
Another possible use for translate is to remove unwanted characters, such as maybe vowels. The TRanslate() function makes this possible. Just specify the characters that you'd like to get rid of in the "from" string, and omit them from the "to" string as shown in the following example:
translate(//book/author,'aAeEiIoOuUyY','') All of a sudden, J.R.R. Tolkien becomes J.R.R. Tlkn.