From: Pieter D. <pie...@gm...> - 2010-08-09 09:51:04
|
On Mon, Aug 9, 2010 at 6:29 AM, Dmitriy Shabanov <sha...@gm...>wrote: > On Sun, 2010-08-08 at 23:28 +0200, Pieter Deelen wrote: > > > The spec you refer to states: > "The behavior of the function if the argument is omitted is exactly > the same as if the context item had been passed as the argument.", > i.e., string() is equivalent to string(.). Hence, ()/string() should > return exactly the same value as ()/string(.). > > > I totally agree that it must be same, but the question "what should > empty(()/string(.)) return?" > > Let go step by step: > ()/string(.) have equivalent string( () ). The spec quite clear on this ( > http://www.w3.org/TR/xpath-functions/#func-string ) : > > =================================================================== > 2.3 fn:string > fn:string() as xs:string > fn:string($arg as item()?) as xs:string > > Summary: Returns the value of $arg represented as a xs:string. If no > argument is supplied, the context item (.) is used as the default argument. > The behavior of the function if the argument is omitted is exactly the same > as if the context item had been passed as the argument. > > If the context item is undefined, error [err:XPDY0002]XP is raised. > > > *If $arg is the empty sequence, the zero-length string is returned.* > =================================================================== > > So, getting empty( xs:string("") ) and it return false, because ( > http://www.w3.org/TR/xpath-functions/#func-empty ) > > =================================================================== > 15.1.4 fn:empty > fn:empty($arg as item()*) as xs:boolean > > Summary: If the value of $arg is the empty sequence, the function returns > true; otherwise, the function returns false. > =================================================================== > > the xs:string("") is not a empty sequence. > > That mean empty( ()/string(.) ) == empty( ()/string() ) == false > Let's forget about the string function for a moment and introduce function f: declare function local:f($elt as element()) { "f" }; Then if I evaluate the following expression (<a/>, <b/>)/local:f(.) I expect (and get from both eXist 1.4 and Saxon 9) ("f", "f") So the function f is called twice, the first time with <a/> as parameter, and the second time with <b/>. Similarly, (<a/>)/local:f(.) returns ("f"): the function f is called once, for <a/>. So if I evaluate ()/local:f(.) I would expect the function f to be called not at all and the empty sequence as result. Instead, eXist shows the following error: "The actual cardinality for parameter 1 does not match the cardinality declared in the function's signature: local:f($a as element()) item()*. Expected cardinality: exactly one, got 0." I.e., eXist tries to call the function f, but this fails because the function's signature does not allow it. Saxon gives me the result I expect. Pieter > |