[xquery-talk] Accessing empty namespaced elements in non-empty contexts

Michael Kay mike at saxonica.com
Mon Apr 2 12:19:04 PDT 2018


XML doesn't allow you to bind a prefix to the thing-that-is-not-a-namespace.

With XML namespaces 1.1, the declaration xmlns:x="" doesn't bind x to anything, it unbinds x. Within the scope of this (un)declaratiion, the prefix x cannot be used.

It makes sense for XQuery to do the same thing. The rules are in §3.9.1.2:

If the namespace URI is a zero-length string and the implementation supports [XML Names 1.1] <https://www.w3.org/TR/xquery-31/#XMLNAMES11>, any existing namespace binding for the given prefix is removed from the in-scope namespaces <https://www.w3.org/TR/xquery-31/#dt-in-scope-namespaces> of the constructed element and from thestatically known namespaces <https://www.w3.org/TR/xquery-31/#dt-static-namespaces> of the constructor expression. If the namespace URI is a zero-length string and the implementation does not support [XML Names 1.1] <https://www.w3.org/TR/xquery-31/#XMLNAMES11>, a static error is raised [err:XQST0085 <https://www.w3.org/TR/xquery-31/#ERRXQST0085>]. It isimplementation-defined <https://www.w3.org/TR/xquery-31/#dt-implementation-defined> whether an implementation supports [XML Names] <https://www.w3.org/TR/xquery-31/#XMLNAMES> or [XML Names 1.1] <https://www.w3.org/TR/xquery-31/#XMLNAMES11>.

Michael Kay
Saxonica

> On 2 Apr 2018, at 20:00, Joe Wicentowski <joewiz at gmail.com> wrote:
> 
> Hi all,
> 
> A common question for beginners is how to access empty namespaced elements in non-empty contexts.  The easiest answer is to use a wildcard.  For example, we use one here inside the curly braces:
> 
>   let $x := <x><y/></x>
>   return
>     <z xmlns="foo">{ $x/*:y }</z>
> 
> As expected, this query returns:
> 
>   <z xmlns="foo"><y xmlns=""/></z>
> 
> The other method I know of is to use the URI-qualified name:
> 
>   let $x := <x><y/></x>
>   return
>     <z xmlns="foo">{ $x/Q{}y }</z>
> 
> A third method occurred to me, but it does not work, and I haven't been able to pin down the reason despite reading the spec.  The idea is to bind the empty namespace URI to a namespace prefix, e.g., "my":
> 
>   declare namespace my="";
>   
>   let $x := <x><y/></x>
>   return
>     <z xmlns="foo">{ $x/my:y }</z>
> 
> In BaseX, eXist, and Saxon, this returns err:XPST0081 (https://www.w3.org/TR/xquery-31/#ERRXPST0081 <https://www.w3.org/TR/xquery-31/#ERRXPST0081>).  The location of the error points to the step, "my:y" on the final line.
> 
> Can anyone enlighten me on the reason this 3rd method is invalid?  Bonus points for an explanation that includes why I cannot bind a namespace prefix to the empty namespace, but I can access it via *: and Q{}?
> 
> Thanks,
> Joe
> _______________________________________________
> talk at x-query.com
> http://x-query.com/mailman/listinfo/talk

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://x-query.com/pipermail/talk/attachments/20180402/ca29b62d/attachment.html>


More information about the talk mailing list