Why does my XQuery fail when I override the default namespace?

The following XQuery:

let $doc := <root><book>1</book></root>
return
    <books> {
        for $book in $doc//book
        return <bookid>{$book/text()}</bookid>
    } </books>

... works fine for me and returns:

<books><bookid>1</bookid></books>

I need to specify that the result fragment is defined in a different namespace; but when I change the XQuery into:

let $doc := <root><book>1</book></root>
return
    <books xmlns="myNamespace"> {
        for $book in $doc//book
        return <bookid>{$book/text()}</bookid>
    } </books>

...then no <bookid>’s are returned. Why?

The problem is caused by the fact that in XQuery the selection of a new default namespace (xmlns="myNamespace") also affects the XPath expressions contained in that scope; so, your XQuery is selecting all <book> elements in the “myNamespace” namespace, rather than in the (default) one used to define the input document. This mechanism usually makes life easier for XQuery developers; but in this case it causes some headaches. The cleanest solution is probably to avoid using the default namespace and use a prefixed one instead, like in this example:

let $doc := <root><book>1</book></root>
return
    <ns:books xmlns:ns="myNamespace"> {
        for $book in $doc//book
        return <ns:bookid>{$book/text()}</ns:bookid>
    } </ns:books>

... which returns:

<ns:books xmlns:ns="myNamespace"><ns:bookid>1</ns:bookid></ns:books>


Next Question!

Can I create a library of XQuery functions?

Submit Your DataDirect XQuery Tip or Trick

Tell us your XQuery Tip or Trick – if it gets published on our site, you’ll receive a

$10.00 Amazon.com
Gift Certificate!

Submit your tip or trick today.