The preceding section discussed how addressing works in XPath. The language is also capable of performing simple computations that return strings, booleans, or numbers. XForms defines the term Computed Expression to represent this special usage of XPath.
3.4.1 Operators3.4.1.1 Arithmetic basics (+, -, *, div, and mod)XPath includes all the arithmetic basics: plus, minus, multiply, divide, modulus, and unary minus (which negates the single operand). All of these operators convert their operands into numbers if needed, as with a call to number( ).
3.4.1.2 Equality comparisons (=and !=)Comparing whether one thing is the same as another or not is straightforward, though some of the type combinations get interesting. When comparing two node-sets, the comparison looks at the individual nodes. If any node in the left-hand node-set has a string-value that meets the equals or not-equals comparison with the string-value of any node in the right-hand node-set, the overall comparison succeeds. Similarly, if one side is a node-set and the other side is either a string or a number, the comparison will succeed if any node in the node-set meets the comparison. In comparing a boolean and any other datatype, the other datatype is converted as with a call to boolean( ) before comparison. Otherwise, if at least one object to be compared is a number, then the other object is converted as with a call to number( ) before comparison. Finally, comparisons between the same datatypes for strings, numbers, and booleans can be done directly. 3.4.1.3 Relational comparisons (<, >, <=, and =>)The rules for relational comparisons follow the same rules as above when at least one operand is a node-set. In all other cases, both operands are converted if necessary into a number, as with a call to number( ) before comparison. 3.4.1.4 Boolean operations (or, and)Boolean expressions can be connected together with logical or and and operators. (Note that not( ) is available also, but as a function, not an operator) 3.4.1.5 Node-set unions (|)A final operator performs a union operation on a node-set. Note that the resulting node-set (like all node-sets) will contain no duplicate nodes. 3.4.2 FunctionsXPath defines a number of built-in functions, and XForms adds a few more. This section lists every built-in function. Note that even though function parameters are unnamed in XPath, the descriptions below include parameter names for descriptive purposes.
This example returns the 4th para element child of the context node (or an empty node-set if there is no 4th para element): para[position()=4]
This example returns the last para element child of the context node: para[position()=last()]
This example returns the number of item elements that are children of the items element: count( items/item )
Normally, this function is used to return the single node with an ID that matches the string value passed in as a parameter. When a space-separated list or a node-set is passed in, it will return the union of all nodes that individually match the IDs. This function normally appears on the left-hand side of a path expression.
This example selects the element with the unique ID "taxtable" (if any) and returns a node-set of all the rate element children: id("taxtable")/rate
Only the first node (in document order) of the node-set is considered. When called with no parameters, the local name of the context node is returned. This example returns the local name of the element xforms:model, which is "model": local-name(xforms:model)
Only the first node (in document order) of the node-set is considered. For anything other than attribute and element nodes, the return value will always be the empty string. When called with no parameters, the namespace URI of the context node is returned. This example returns the namespace URI of the element xforms:model, which is http://www.w3.org/2002/xforms: namespace-uri(xforms:model)
For other node types, returns the same value as local-name( ). When called with no parameters, the name of the context node is returned. This example returns the QName of the element xforms:model, which is "xforms:model": name(xforms:model)
Conversion from other datatypes proceeds according to the following rules:
When called with no parameters, the converted value of the context node is returned. This example returns a string equal to the string-value of the title element, which in HTML would be a single text node: string(/html/head/title)
The example combines all four string parameters into a single string, "Hello World!": concat( 'Hello', ' ', 'World', '!')
This example returns true: starts-with('Hello World!', 'H')
This example returns true: contains('Hello World!', 'r')
If the substr string is found within the larger string, this function returns the portion of the src string up to and not including the first matched substr. If not found, returns the empty string. This example returns the string "1999": substring-before("1999-04-01","-")
If the substr string is found within the larger string, this function returns the portion of the src string after and not including the first matched substr string. If not found, returns the empty string. This example returns the string "04-01": substring-after("1999-04-01","-")
The returned substring is determined by starting with the startth character, and continuing on for length characters. If the length parameter is omitted, the returned string continues on to the end of the src string. The following example returns "34", and the second following example returns "345": substring("12345", 3, 2) substring("12345", 3)
When called with no parameters, returns the number of characters in the context node converted to a string. This example returns 12: string-length("Hello World!")
This function removes all leading and trailing whitespace, and all other consecutive whitespace characters are replaced with a single space. When called with no parameters, returns the normalized value of the context node converted to a string. This example returns "Hello World!": normalize-space(" Hello World! ")
Characters from the removechars string replaced with characters from the corresponding position in the replacechars string. The removechars string may be longer than the replacechars string, in which case the additional characters are simply removed from the src string.
The first example returns "hello world!", and the second example returns "hello world" (note that the exclamation point is gone): translate("Hello World!", "HW", "hw") translate("Hello World!", "HW!", "hw")
Other datatypes are converted according to the following rules:
When called with no parameters, the converted value of the context node is returned. This example returns true if the Location Path a/b happens to select one or more nodes; otherwise, it returns false: boolean(a/b)
This example returns false if the Location Path a/b happens to select one or more nodes; otherwise, it returns true: not(a/b)
This example returns true: true( )
This example returns false: false( )
This function examines the context node and returns true if the declared language (with an xml:lang attribute) matches. The comparison takes into account the rules for language identifiers, such that a search for "en" will still match "en-gb". If the context node doesn't contain an xml:lang attribute, the nearest ancestor element node with an xml:lang attribute will be consulted. If no xml:lang declaration can be located, the return value is false. For an XPath data model matching the following XML: <root xml:lang="x-klingon"> <context/> </root> With context as the context node, this example returns true: lang("x")
Other datatypes are converted according to the following rules:
When called with no parameters, the converted value of the context node is returned. The following example returns NaN: number("three")
The value of each individual node is determined by converting the string-value to a number (as with number( )). If any individual node converts to NaN, the overall result is NaN. For an XPath data model representing the following XML: <operands> <operand>3.14</operand> <operand>42</operand> <operand>0</operand> <operand>0.86</operand> </operands> The following XPath expression returns 46: sum(/operands/operand)
(NaN, Infinity, and -Infinity are passed through unchanged.) The first example returns 3, and the second example returns -4: floor(3.14) floor(-3.14)
(NaN, Infinity, and -Infinity are passed through unchanged.) The first example returns 4, and the second example returns -3: ceiling(3.14) ceiling(-3.14)
In the event of a tie, the larger result is returned. NaN, Infinity, and -Infinity are passed through unchanged. The first example returns 4. The second example returns -3. round(3.5) round(-3.5)
This function differs from boolean( ) in that it takes into account XML Schema rules: "true" or "1" produces true, and "false" or "0" produce false. This example, as might be used when the value of the b element is of the type xs:boolean, returns an XPath boolean value that matches the XML Schema value of the node: boolean-from-string(a/b)
This function evaluates the boolean test parameter, and returns trueval if the test is true, or falseval otherwise. Note that all three parameters are always evaluated no "short circuit" evaluation takes place. If the evaluation of a/b yields true, this example returns "it worked", and otherwise returns "it failed": if(boolean-from-string(a/b), "it worked", "it failed")
The average is computed as the sum( ) divided by the count( ) of the value of each individual node, converted into a number (as with number( )). For an XPath data model representing the following XML: <operands> <operand>3.14</operand> <operand>42</operand> <operand>0</operand> <operand>0.86</operand> </operands> The following XPath expression returns 11.5: avg(/operands/operand)
The value of each individual node is determined by converting the string-value to a number (as with number( )). A node-set that is empty or that includes nodes that evaluate to NaN will result in a return value of NaN. For an XPath data model representing the following XML: <operands> <operand>3.14</operand> <operand>42</operand> <operand>0</operand> <operand>0.86</operand> </operands> The following XPath expression returns 0: min(/operands/operand)
The value of each individual node is determined by converting the string-value to a number (as with number( )). A node-set that is empty or that includes nodes that evaluate to NaN will result in a return value of NaN. For an XPath data model representing the following XML: <operands> <operand>3.14</operand> <operand>42</operand> <operand>0</operand> <operand>0.86</operand> </operands> The following XPath expression returns 42: max(/operands/operand)
For the purposes of this function, "non-empty" means a string-value of one or more characters. This can be useful when computing an average that disregards empty values. For an XPath data model representing the following XML: <operands> <operand>3.14</operand> <operand>42</operand> <operand/> <operand>0.86</operand> </operands> The following XPath expression returns 15.333333333333334: sum(/operands/operand) div count-non-empty(/operands/operand)
XForms includes the notion of repeating content that holds a current index. This function is an accessor for that index. A full example requires a "repeating structure" setup with XForms user interface markup. Further information and examples are available in Chapter 6.
XForms specifies certain property strings that can be retrieved with this function:
This example returns 1.0, assuming the processing environment claims to be XForms 1.0 compliant: property("version")
The format returned by this function is a lexical XML Schema xs:dateTime format. If time zone information is unavailable from the system, an implementation default is used so that comparisons will still work. This example returns 2003-02-14T09:13:02Z, when called at that point in time: now( )
XPath allows multiple separate instance data areas. This function returns the root node of the specified instance data. Normally, this function appears on the left-hand side of a path expression. This example returns a node-set consisting of the rate element node from the instance named "taxtable": instance('taxtable')/rate
This function computes a number of days relative to an epoch of 1970-01-01, and is most useful when two xs:date values need to be compared. This example returns -1: days-from-date("1969-12-31")
This function computes a signed fractional number of seconds relative to an epoch of 1970-01-01T00:00:00Z, and is useful when two xs:dateTimes need to be compared. This example returns the large number of seconds representing the current date and time: seconds-from-dateTime(now())
This function computes a fractional number of seconds that is equivalent in length to the dayTimeDuration parameter (formatted according to XML Schema rules).
This example returns 297001.5: seconds("P3DT10H30M1.5S")
This function computes a whole number of months that is equivalent in length to the yearMonthDuration parameter (formatted according to XML Schema rules).
This example returns 14: months("P1Y2M") 3.4.2.1 Extension FunctionsThe XPath specification itself is silent on the issue of implementation-specific or "extension" functions. XSLT, on the other hand, defines a framework in which extension functions can be used. Similarly, XForms provides a general outline of how extension functions fit in. Extension functions are easily recognizable since all built-in functions are unprefixed names, while all extension functions contain a leading prefix and a colon character. A group of volunteers at the web site http://www.exslt.org/ collect and maintain a number of extension functions that are suitable for use in XForms. The main disadvantage of extension functions is non-portability. Since these functions are implementation-specific, any form that uses them will only work inside implementations that also support the functions used. To make this explicit, any form that uses extension functions should list the QNames of the functions in the functions attribute of the model element. For example, a form that needed a few more date and time functions from the EXSLT library would use the following declaration: <xforms:model xmlns:exslt="http://exslt.org/dates-and-times" functions="exslt:leap-year exslt:month-name exslt:day-name"> ... Upon initialization, the XForms Processor will check to make sure that all the listed functions are available and immediately signal an error if they are not. For this reason, only functions that are absolutely necessary to the proper functioning of the form should be listed here. On the other hand, failing to list a function here will likely cause a run-time XPath error in some implementations, such as when the user is filling out the form and gets to the point where the XPath engine will try (and fail) to locate the extension function. |