Read XSLT 2.0 and XPath 2.0 Programmer's Reference, 4th Edition Online
Authors: Michael Kay
will be retained as the last character of each substring in the tokenized sequence. Another approach, if you are using XSLT, is to use the
A similar technique is possible when there are no separators available. Suppose that the input is alphanumeric, and you want to break it into a sequence of alternating alphabetic and numeric tokens, so that the input
W151TBH
is split into the three strings
(“W”, “151”, “TBH”)
. Here's how to do this:
tokenize(replace($input, “([0-9]+|[A-Za-z]+)”, “$1#”), “#”)[.]
The predicate
[.]
at the end of this expression causes zero-length strings in the result to be filtered out (there will be a zero-length string at the end of the sequence).
See Also
matches()
on page 828
replace()
on page 862
Regular Expressions
: Chapter 14
trace
The
trace()
function is used to produce diagnostic output. The format and destination of the output is implementation-defined.
Signature
Argument | Type | Meaning |
value | item()* | A value that is to be displayed in the diagnostic output |
message | xs:string | A message that is to be output along with the displayed value |
Result | item()* | The function returns the displayed value , unchanged |
Effect
The detailed effect of this instruction depends on the implementation; some implementations might ignore it entirely. The idea of the function is that when it is evaluated, a message should be produced to some diagnostic output stream (perhaps a log file or perhaps an interactive console) showing the message string and the contents of the supplied value. The function then returns this value, and execution continues normally.
Note that since the order of execution of different expressions is undefined, the trace output will not necessarily be strictly sequential, and it may be difficult to see what is going on when the same
trace()
expression is evaluated repeatedly. This problem can be reduced if the message, rather than being a simple literal string, is constructed from variables that provide some context.
The specification doesn't say whether the presence of the
trace()
function should or should not affect the optimizer's evaluation strategy. Some implementors may decide that to make the trace output intelligible, certain optimizations should be suppressed; others may decide that the execution strategy with tracing should be as close as possible to the execution strategy without tracing, to reduce the risk of so-called Heisenbugs, in which the behavior of the expression changes when debugging is switched on.
Usage and Examples
Suppose you are having problems understanding why the function call
sum(//@price)
is returning NaN. Try changing it to:
sum(//trace(@price, “price value”))
to see the price values that are being used in the computation.
In the Saxon implementation, when you trace a sequence, you get one message for each item in the sequence. Saxon pipelines the evaluation of sequences, and tracing doesn't change the pipeline, so you might find that the evaluation of different sequences is interleaved. This can be confusing, but it gives you a faithful picture of what is happening internally. Other implementations might give you one message for the entire sequence, and might break the evaluation pipeline in order to output the message.
Sometimes you might just want to output a value that is not actually used in the computation. In this case, you can usually use an empty sequence as the value, and put the required value into the message—just remember that the
trace()
function will then return an empty sequence. For example, you could write:
sum(//(trace((),concat(“reading price for ”, string(@code)), @price)