<?xml version="1.0" encoding="UTF-8"?>
<essay xml:lang="en" version="5.0" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:gal="http://norman.walsh.name/rdf/gallery#" xmlns:foaf="http://xmlns.com/foaf/0.1/">
<info>
    
    
    
    
    
    
    
    
    
    
<title>Using XQuery in anger</title><biblioid class="uri">http://norman.walsh.name/2008/07/02/xquery</biblioid>
<volumenum>11</volumenum>
<issuenum>49</issuenum>
<pubdate>2008-07-02T15:29:10-04:00</pubdate>
<author>
      <personname>
<firstname>Norman</firstname>
	<surname>Walsh</surname>
</personname>
    </author>
<copyright>
      <year>2008</year>
      <holder>Norman Walsh</holder>
    </copyright>
<abstract>
<para>As XQuery, in the form of my first real work project, kept me busy
over the past month or so, it seems logical to start blogging again
with some lessons learned.</para>
</abstract>
<dc:subject rdf:resource="http://norman.walsh.name/knows/taxonomy#MarkLogic"/>
<dc:subject rdf:resource="http://norman.walsh.name/knows/taxonomy#XML"/>
<dc:subject rdf:resource="http://norman.walsh.name/knows/taxonomy#XQuery"/>
</info>

<para xml:id="p1">What <link xlink:href="/2008/05/13/joy">I said before</link>
still applies: I remain impressed with XQuery as a programming language
for building web applications on top of a product like
<citetitle xlink:href="http://www.marklogic.com/product/marklogic-server.html">Mark Logic Server</citetitle>.
</para>

<para xml:id="p2">I have a slightly odd relationship with XQuery because I was on the
<link xlink:href="http://www.w3.org/Style/XSL/">XSL Working Group</link>
when <link xlink:href="http://www.w3.org/TR/xpath20/">XPath 2.0</link>,
<link xlink:href="http://www.w3.org/TR/xslt20/">XSLT 2.0</link>, and
<link xlink:href="http://www.w3.org/TR/xquery/">XQuery 1.0</link> were being
defined. A lot of that work was done jointly, so I've seen a fair bit
of XQuery go by, but I wasn't paying that much attention to the XQuery-only
bits [Clearly! See below. -ed].</para>

<para xml:id="p3">My first real work project was a proof-of-concept exercise. In broad
strokes, I had to take collections of items from five or six different
XML formats, present them reasonably well in several formats,
provide a uniform search interface (full-text and by discrete facets)
across all the formats, allow the user to select items and build a new
document from those items, and provide some simple forms for adding
new items or changing existing items.</para>

<para xml:id="p4">It's a few thousand lines of XQuery (and some JavaScript
libraries, but that's another topic) and it works just they way I want
it to. The requirements have shifted a little bit once or twice and
XQuery proved quite agile.</para>

<para xml:id="p5">Which isn't to say without annoyance.</para>

<para xml:id="p6">First, there's the issue that <foaf:nick>Micah</foaf:nick>
<link xlink:href="http://dubinko.info/blog/2008/05/21/xquery-annoyances/">identified</link>. Careless use of path expressions littered some of my HTML with
random source elements. For most of them, I found a cast to
<code>xs:string</code> sufficient. For others, as <foaf:nick>Jeni</foaf:nick>
points out in her comment, you really do need to do the recursive function
thing.</para>

<para xml:id="p7">And, well, there's that whole recursive-descent, walk the tree
yourself, approach to converting from one XML vocabulary to another.
That's just a drag. If XSLT has it and XQuery doesn't, XQuery is the
weaker for it. Formatting dates and times, generating unique
identifiers, grouping, who thought these were things you didn't need
in XQuery?</para>

<para xml:id="p8">If you're familiar with variables in XSLT, it's tempting to think
of the XQuery <code>let</code> statement as roughly analogous. So you
write things like this:</para>

<programlisting>
let $foo := <replaceable>some expression</replaceable>
something[@class=$foo]|something-else[contains(@role,$foo)]
</programlisting>

<para xml:id="p9">And you discover that you've left out the <code>return</code>
statement. Careful examination of the XQuery grammar
will reveal that <code>let</code> is only allowed in a FLWOR expression,
it's just that the <code>for</code>, <code>where</code>, and <code>order by</code>
parts are optional. The <code>return</code> isn't. I kid you not.</para>

<para xml:id="p10">Speaking of the <code>return</code> statement, am I the only one
routinely tempted to put it at the end of function bodies, where it
doesn't belong? Yeah, maybe I am.</para>

<para xml:id="p11">Finally, there is a small corner of the XQuery specification which 
is deeply, fundamentally perverse. XQuery allows you to specify the default
element namespace so that the bare element name “<literal>somename</literal>”
in your query will be in the specified namespace. Unfortunately, doing
that makes it impossible to write the name of an element that is not
in a namespace. So the XQuery specification allows you to bind a
prefix to the empty string:</para>

<programlisting>declare namespace l = ""</programlisting>

<para xml:id="p12">You can then refer to elements in no namespace using that prefix,
“<literal>l:someothername</literal>”. That is just wrong, wrong, wrong!
</para>

<para xml:id="p13">I concede that within the context of XQuery, it works and is
entirely consistent, but it still makes me want
to barf on my shoes. The problem is that the element name
“<literal>&lt;l:someothername/&gt;</literal>” in an actual XML
document <emphasis>can never be</emphasis> in no namespace. So the
XQuery syntax in this regard seems like a really bad compromise to my
eyes.</para>

<para xml:id="p14">None of these problems can be fixed at this stage, but none of them
are show-stoppers. They're just idiosyncratic. I know Perl, I can deal
with idiosyncracy.</para>

</essay>

