Read XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition Online
Authors: Michael Kay
Examples
Expression | Result |
substring-before(“my.xml”, “.”) | “my” |
substring-before(“my-xml.xml”, “xml”) | “my-” |
substring-before(“my.xml”, “”) | “” |
substring-before(“my.xml”, “#”) | “” |
Usage and Examples
An example of the use of
substring-after()
and
substring-before()
to process a whitespace-separated list of tokens is given under
substring-after()
on page 887.
If the only reason for using
substring-before()
is to test whether the string has a given prefix, use
starts-with()
instead. You could write:
if (substring-before($url, ‘:’)=‘https’) then …
but the following is simpler:
if (starts-with($url, ‘https:’)) then …
In XPath 1.0, the
substring-before()
and
substring-after()
functions were often used in conjunction to find and replace portions of a string. In XPath 2.0, this kind of string manipulation is much easier using regular expressions, as offered by the
replace()
function.
See Also
contains()
on page 730
replace()
on page 862
starts-with()
on page 875
substring()
on page 883
substring-after()
on page 885
sum
The
sum()
function calculates the total of a sequence of numeric values or durations.
For example, if the context node is the element
sum(@*)
returns 50. (The expression
@*
is a sequence containing all the attributes of the context node.)
Changes in 2.0
This function is generalized in XPath 2.0 so that it can sum over all the numeric types, and also over durations.
In XPath 1.0 the function returned NaN if the sequence contained a value that could not be converted to a number. In XPath 2.0 (even under backward-compatibility mode) this situation causes a failure.
Signature
Argument | Type | Meaning |
sequence | xs:anyAtomicType* | The set of items to be totaled |
zero-value (optional) | xs:anyAtomicType | The value to be returned when the sequence is empty |
Result | xs:anyAtomicType | The total of the values in the sequence |
Effect
Although the function signature states that the input sequence must consist of atomic values, the function calling rules ensure that the actual argument can be a sequence of nodes—the nodes in this sequence will be atomized, which extracts their typed values. If the source document has been validated using a schema, then the type of the resulting values depends on the schema, while if it has not been validated, the result of atomization will be untyped atomic values.
Any untyped atomic values in the sequence are converted to
xs:double
values. A runtime error is reported if this conversion fails. If the sequence contains any NaN (not-a-number) values, which might happen if you do the conversion yourself by calling the
number()
function, then the result of the function is NaN.
The values in the sequence are added using the
+
operator. An error is reported if there are values that cannot be added using the
+
operator. This will happen if the sequence contains values of types other than the numeric types, the duration types, and
xs:untypedAtomic
, or if it contains a mixture of durations and other types. If you are totaling durations, all the durations must either be of type
xs:dayTimeDuration
or they must all be of type
xs:yearMonthDuration
—you cannot mix the two, and you cannot use duration values unless they match one of these subtypes.
If the input sequence is empty, then the value returned is the value specified in the
zero-value
argument. If this argument is omitted, the return value for an empty sequence is the
xs:integer
value 0. The purpose of this argument is to allow a return value to be specified that has the appropriate type, for example, an
xs:double
0.0e0 for use when totaling doubles, or the value
PT0 S
when totaling
xs:dayTimeDuration
values. This is needed because there is no runtime type information associated with an empty sequence—an empty sequence of
xs:double
values does not look any different from an empty sequence of
xs:dayTimeDuration
values.
Examples
Expression | Result |
sum((1, 2, 3, 4)) | 10 ( xs:integer ) |
sum((1, 2, 3, 4.5)) | 10.5 ( xs:decimal ) |
sum((1, 2, 3.5e0, 4.5)) | 11.0e0 ( xs:double ) |
sum(()) | 0 ( xs:integer ) |
sum((), 0.0e0) | 0.0e0 ( xs:double ) |
sum((xs:dayTimeDuration(“P3D”), | xs:dayTimeDuration(“P4DT12H”) |
xs:dayTimeDuration(“PT36H”))) | |
sum((), xs:dayTimeDuration(“PT0 S”)) | xs:dayTimeDuration(“PT0 S”) |
Usage
The
sum()
function can be used to create totals and subtotals in a report. It is also useful for calculating geometric dimensions on the output page.
A problem that sometimes arises is how to get a total over a set of values that aren't present directly in the source file, but are calculated from it. For example, if the source document contains
price
and
sales
, how would you calculate the total sales revenue, which is obtained by multiplying
price
by
sales
for each book, and totaling the result over all books? Or, how would you total a set of numbers if each one has a leading
$
sign, which you need to strip off first? In XPath 1.0 this was difficult to achieve, but the solution in XPath 2.0 is simple: