Convoluted history here. The XPath 1.0 spec is:
<quote>
Function: number string-length(string?) <>
The string-length
<https://www.w3.org/TR/1999/REC-xpath-19991116/#function-string-length> returns
the number of characters in the string (see [3.6 Strings]
<https://www.w3.org/TR/1999/REC-xpath-19991116/#strings>). If the argument is
omitted, it defaults to the context node converted to a string, in other words
the string-value
<https://www.w3.org/TR/1999/REC-xpath-19991116/#dt-string-value> of the context
node.
</quote>
(Yes, that's the entire spec). In 1.0, if you supplied something other than a
string, it would be implicitly converted to a string by calling the string()
function, by virtue of the rules for function calls. Recall also that 1.0 only
had a context node, not a context item (without something like the "!"
operator, there was no way the context item could be a number.)
In 2.0 the spec became:
<quote>
7.4.4 fn:string-length
fn:string-length() as xs:integer
fn:string-length($arg as xs:string?) as xs:integer
Summary: Returns an xs:integer equal to the length in characters of the value
of $arg.
If the value of $arg is the empty sequence, the xs:integer 0 is returned.
If no argument is supplied, $arg defaults to the string value (calculated using
fn:string() <https://www.w3.org/TR/xquery-operators/#func-string>) of the
context item (.). If no argument is supplied and the context item is undefined
an error is raised: [err:XPDY0002
<http://www.w3.org/TR/xpath20/#ERRXPDY0002>]XP.
</quote>
Spot the difference.
I don't know if it was recognized at the time, but the way that is written
means that string-length() and string-length(.) do different things. If the
context item is a number, string-length() converts the number to a string,
whereas string-length(.) gives you a type error unless XPath 1.0 compatibility
mode is in force.
If (like other functions that take the context item as an implicit argument)
the spec had simply said that the first argument defaults to "." (the context
item), it would still have been backwards compatible with 1.0 in all cases when
backwards compatibility was enabled, without introducing this anomaly.
Michael Kay
Saxonica
On 8 Jun 2019, at 01:52, Elisa Beshero-Bondar ebbondar(_at_)gmail(_dot_)com
<xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> wrote:
Dear XSL list,
We are perplexed by a discrepancy between applying the string-length()
function directly to a numerical argument and using simple map to perform
what we expected would be the same operation. string-length(5) returns an
error, as expected. oXygen reports: "XPath failed due to: Required item type
of first argument of fn:string-length() is xs:string; supplied expression (5)
has item type xs:integer". eXist-db reports: "xs-integer(5) is not a sub-type
of xs-string".
When we use simple map, though, the behavior is different:
5 ! string-length() returns a string-length of 1
05 ! string-length() returns a string-length of 2
0.5 ! string-length() returns a string-length of 3
00.5 ! string-length returns a string-length of 3
05 ! string-length() returns a string-length of 1
Can someone please explain why simple-map does not raise the type error that
we see when we write the numerical argument directly inside the function
parentheses?
Thanks for your help!
Elisa
--
Elisa Beshero-Bondar, PhD
Associate Professor of English
University of Pittsburgh at Greensburg
Humanities Division
150 Finoli Drive
Greensburg, PA 15601 USA
E-mail: ebb8(_at_)pitt(_dot_)edu <mailto:ebb8(_at_)pitt(_dot_)edu>
XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/293509> (by
email <>)
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--