Support #4264
closedWarning to use xsl:sequence though always a single value is returned
0%
Description
I have an XSLT with some helper functions. After updating from Saxon 9.8 to 9.9 (to be precise: 9.9.1.4), I now get warnings like the following:
Warning at function subcheck:string_to_amount on line 92 of irt_functions.xsl:
SXWN9000: A function that computes atomic values should use xsl:sequence rather than xsl:value-of
Warning at function subcheck:imsc1_signalling_present on line 108 of irt_functions.xsl:
SXWN9000: A function that computes atomic values should use xsl:sequence rather than xsl:value-of
Warning at function subcheck:ttml_style_chain_exists on line 119 of irt_functions.xsl:
SXWN9000: A function that computes atomic values should use xsl:sequence rather than xsl:value-of
(this output actually results from using this file: https://github.com/IRT-Open-Source/xcf_suite_ttml/blob/d10e78a223fad983a31082cb1603568c039f35db/irt_functions.xsl)
All of the affected functions have an explicitely defined returned type that is an atomic value (i.e. a single atomic value, e.g. xs:decimal
or xs:boolean
). Unless I have overseen something, it is fine then to use xsl:value-of
instead of xsl:sequence
(I like to restrict the function result as early as possible). So the warning should not appear in such cases.
Please find attached a minimum test case that is adopted from the first occurence in the functions file mentioned above. I used the following cmdline:
java -jar saxon9he.jar -s:function_warning.xslt -xsl:function_warning.xslt -o:output.xml
And the following output:
Warning at function test:string_to_amount on line 4 of function_warning.xslt:
SXWN9000: A function that computes atomic values should use xsl:sequence rather than xsl:value-of
Files
Updated by Martin Honnen over 5 years ago
I think the point of the warning is to tell you that xsl:value-of
is the wrong attempt to "return" a xs:decimal
or any other atomic value (or in my opinion any other value you compute with XPath) as xsl:value-of
creates a text node. So doing <xsl:value-of select="xs:decimal(replace($s, '^([-+]?\d*\.?\d+).*$', '$1'))"/>
creates a text node with that decimal value in the function body and then is converted back to a decimal only because of your as="xs:decimal"
declaration.
So if you want to write a function to return a xs:decimal
the proper way in XSLT 2 and later is to use <xsl:sequence select="xs:decimal(replace($s, '^([-+]?\d*\.?\d+).*$', '$1'))"/>
.
Remember that there is no difference between a single value and sequence of exactly one value so don't let that name xsl:sequence
confuse you to assume you are broadening the return type.
Updated by Martin Honnen over 5 years ago
See https://www.w3.org/TR/xslt-30/#value-of:
The xsl:value-of instruction is evaluated to construct a new text node; the result of the instruction is the newly constructed text node.
Updated by Michael Kay over 5 years ago
The warning is because converting an atomic value to a text node and then back to an atomic value is expensive. It can't always be optimized away because there are edge cases where you don't get back the same atomic value that you started with.
Updated by Stefan Pöschel over 5 years ago
Ah, I see. I was under the (wrong) impression that xsl:value
is a special case of xsl:sequence
, limited to a single atomic value. So this is definitely not a bug - but a good hint which helps to improve my coding style. Thank you for the fast response!
Updated by Michael Kay over 5 years ago
- Tracker changed from Bug to Support
- Status changed from New to Closed
- Assignee set to Michael Kay
Closing this as I believe the question is now resolved. Feel free to re-open if necessary.
Please register to edit this issue