<?xml version='1.0' encoding='utf-8'?>
<?xml-stylesheet href="/style/browser.xsl" type="text/xsl"?>
<essay 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/"
       xml:lang="en"
       version='5.0'>
<info>
<title>Working with JAXP namespace contexts</title>
<volumenum>9</volumenum>
<issuenum>36</issuenum>
<pubdate>2006-03-28T15:57:15-05:00</pubdate>
<date>$Date: 2006-03-28 17:05:01 -0500 (Tue, 28 Mar 2006) $</date>
<author><personname>
<firstname>Norman</firstname><surname>Walsh</surname>
</personname></author>
<copyright><year>2006</year><holder>Norman Walsh</holder></copyright>
<abstract>
<para>The <code>NamespaceContext</code> is the interface that JAXP 
provides for establishing the namespace bindings used when an XPath
expression is evaluated. Unfortunately, as interfaces go, it leaves
a couple of things to be desired. </para>
</abstract>
</info>

<epigraph>
<attribution><personname>
<firstname>Samuel</firstname><surname>McChord Crothers</surname>
</personname></attribution>
<para xml:id='p2'>Try as hard as we may for perfection, the net result
of our labors is an amazing variety of imperfectness. We are surprised
at our own versatility in being able to fail in so many different
ways.
</para>
</epigraph>

<para xml:id='p1'>In a
<link xlink:href="http://www.w3.org/TR/xml-names11/#dt-nwf">namespace
well-formed</link> document, the namespace bindings in effect at any
given point in the document are well-defined and self-evident. They are
the sum of the declarations (and possible undeclarations) that have
occurred in the document tree above the point in question (including
the declarations on the current element, if the point happens to be an
element).</para>

<para xml:id='p3'>So in the context of this document:</para>

<programlisting><![CDATA[<doc xmlns="http://example.org/ns/test"
     xmlns:h="http://www.w3.org/1999/xhtml">
  <select xpath="//h:body"/>
</doc>]]></programlisting>

<para xml:id='p4'>The XPath expression in the <tag
class="attribute">xpath</tag> attribute clearly<footnote>
<para xml:id='p19'>For the purpose of this essay, let's ignore the issues associated with
<link xlink:href="http://www.w3.org/2001/tag/doc/qnameids.html#sec-qnames-other">QNames
in content</link> and simply assume that we can recognize them and that they
all use the namespace context to determine their bindings.</para></footnote>
selects all the
elements in the context document that are named
“<literal>body</literal>” and are in the
“<literal>http://www.w3.org/1999/xhtml</literal>” namespace. (It doesn't
say anything about how the context document is established, but that's
ok.)</para>

<para xml:id='p5'>One of the problems with using XPath expressions
outside the XML context is that we lose this mechanism for determining
the namespace bindings. When a QName appears on the
side of a bus or in a string in a
<link xlink:href="http://en.wikipedia.org/wiki/Java_programming_language">Java</link>
program, what does it mean? Consider:</para>

<programlisting>xpath.evaluate ("//t:p", doc);</programlisting>

<para xml:id='p6'>What's the namespace binding for <literal>t:</literal>?
</para>

<para xml:id='p20'>The answer, in the case of
<link xlink:href="http://en.wikipedia.org/wiki/JAXP">JAXP</link>,
is in the <interfacename>NamespaceContext</interfacename> interface.
You can ask the
<interfacename>XPath</interfacename> object for a 
<interfacename>NamespaceContext</interfacename> and subsequently
ask that context what's bound to the prefix in question:</para>

<programlisting>NamespaceContext nc = xpath.getNamespaceContext();
String uri = nc.getNamespaceURI("t");</programlisting>

<para xml:id='p7'>So far, so good. Now suppose you want to use the
XPath API to find all the elements in a document that are named
“<literal>body</literal>” and are in the
“<literal>http://www.w3.org/1999/xhtml</literal>” namespace?</para>

<para xml:id='p8'>Easy, right? You (1) write the obvious XPath expression and
(2) cook up a <interfacename>NamespaceContext</interfacename> that binds
the prefix you chose to the HTML namespace and (3) off you go.</para>

<para xml:id='p9'>So, remind me, how do you do that second part exactly?</para>

<para xml:id='p10'>You can't.</para>

<para xml:id='p11'>Well, of course <emphasis>you can</emphasis>, but
it's no where near as easy as it should be. The
<interfacename>NamespaceContext</interfacename> interface doesn't have
an obvious constructor in the JAXP 1.3 API. (And it won't in 1.4
either, but I promise we'll clean this and a bunch of other usability
issues up in 1.5.)</para>

<para xml:id='p12'>To workaround this deficiency, I usually peek inside the
implementation and borrow a non-standard class or I implement the
<interfacename>NamespaceContext</interfacename> interface in some
private, inner class that does just barely enough work to get the job
done. The former is completely non-portable and the latter is a
tedious pain.</para>

<para xml:id='p13'>The last time I blushed my way through this
explanation with a developer, I decided I could at least implement the
interface in some public place so that it could be reused.</para>

<para xml:id='p14'>I won't be surprised to learn that lots of folks,
and lots of frameworks, have already done this. Maybe I could have
saved myself a half-day's labor by pointing to one of those, but I
also wanted to take
<link xlink:href="http://en.wikipedia.org/wiki/NetBeans">NetBeans</link> for
a test drive.</para>

<para xml:id='p15'>The result of my labors is
<link xlink:href="examples/nscontext10.zip">NamespaceContextHelper</link>
(and its
<link xlink:href="examples/javadoc/index.html">JavaDoc</link>)
which you're welcome to borrow and reuse as you see fit. That package
includes the sources, JavaDoc, unit tests, and NetBeans project files.</para>

<para xml:id='p21'>Speaking of unit tests, I've included a couple of extra tests to
highlight common user-errors:</para>

<itemizedlist>
<listitem>
<para xml:id='p22'>If you expect the XPath API to do coherent things, you
<emphasis>must</emphasis> enable namespace support before parsing.</para>
<para xml:id='p23'>Parsing with namespaces disabled (which is unfortunately the
default for the <classname>DocumentBuilder</classname>) results in names
that aren't in a namespace but may have colons. It's just too ugly
to contemplate and it's bound to lead to anomalous XPath results.</para>
</listitem>
<listitem>
<para xml:id='p24'>Setting the default namespace in the 
<interfacename>NamespaceContext</interfacename> <emphasis>does not</emphasis>
allow you to change what unqualified names in your XPath expression match.
</para>
<para xml:id='p25'>Unqualified names in an XPath (1.0) expression always match elements
and attributes in no-namespace, irrespective of the binding in effect.</para>
</listitem>
</itemizedlist>

<section xml:id="netbeans">
<title>NetBeans</title>

<para xml:id='p16'>I've never been a big fan of IDEs, but I have to admit that
NetBeans is a pretty nice environment for Java coding. It certainly
simplified the construction and running of unit tests and offered lots
of useful context-sensitive information. It's only serious flaw is that
it isn't
<link xlink:href="http://en.wikipedia.org/wiki/Emacs">Emacs</link>, but
I'm not sure I can legitimately hold that against it.</para>

<para xml:id='p17'>The out-of-the box Emacs keybindings for NetBeans are ok, but they
don't seem quite right. Maybe I'm being mislead by my own local
Emacs customizations. It's not all my fault though because, for example,
“Alt-W”, which should copy the current selection into the clipboard, sometimes
drops down the “Window” menu. Bleh. I'm sure I can tweak the bindings,
but I haven't tried yet.
</para>

<para xml:id='p18'>Honestly, nice as NetBeans is, I am really, really reluctant to
abandon Emacs for anything. I think I'll get a recent version of
<link xlink:href="http://jdee.sunsite.dk/">JDEE</link> and see if I
can get it to help me sufficiently to keep me as productive as
NetBeans clearly could.</para>

<para xml:id='p26'>It's not obvious that it's going to be practical, NetBeans is
that good.</para>

</section>
</essay>
