Xatapult's XML Blog

20/02/2012

XQuery Namespace Input eq Namespace Output?

Filed under: Opinion,Standards and guidelines — xatapult @ 07:07
Tags: ,

A few month ago I started my first serious programming project using XQuery (on eXist-db). Although the language is easy to master when you already know XPath, it has IMHO a few quirks. Here is, IMHO, the worst:

Namespace output eq namespace input

What would you guess would be the output of the following XQuery fragment:

let $doc := document {
  <Items>
    <Item>1</Item>
    <Item>2</Item>
    <Item>3</Item>    
  </Items>
}
return 
  <out xmlns="http://somenamespace">
    { count($doc//Item) } 
  </out>

Coming from an XSLT background, my guess was:

<out xmlns="http://somenamespace">3</out>

But, surprise, surprise, no such luck. The right answer is:

<out xmlns="http://somenamespace">0</out>

Why 0? Because when you set a default namespace, your embedded XQuery expressions use this as their default namespace too. So the count($doc//Item) was looking for <Item> elements in the somenamespace namespace and not, as I obtusely expected, in the empty namespace…

So if you want the example above to work as intended, you have to refactor the return part to something like:

return 
  <ns:out xmlns:ns="http://somenamespace">
    { count($doc//Item) } 
  </ns:out>

Now why the XQuery committee ever took such a decision is beyond me. To me it looks profoundly illogical and anti-intuitive. Worse, it took me several frustrating hours of very valuable time to find out why my code wasn’t working as expected before I found out that it was not a bug in the XQuery processor but something done by design.

To my knowledge (can somebody enlighten me?) there is not even a way to rewrite the first example in such a way that it will work using default namespaces. There is no way to switch back to the empty namespace in an XPath expression.

So what can we learn from this? `

  • When your XPath expressions unexpectedly turn up empty results, it probably has something to do with a default namespace setting on an embedding element.
  • To prevent this problem from occurring at all, always use a namespace on pieces of XML you design yourselves. This forces you to work with namespace prefixes so it will always work, regardless whether there is a default namespace or not.
  • If you’re not in the position to design the XML but have to work with non-namespaced content, be very careful not to work with default namespaces in your output.

 

Advertisements

1 Comment »

  1. Yeah, the default namespace thing is singularly awful.

    Comment by Norman Walsh — 23/02/2012 @ 15:46 | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: