[jdom-interest] Accessing Child Elements

Peter V. Gadjokov pvg at c-c-s.com
Wed Sep 6 15:01:46 PDT 2000

Following up on my own post... There is another way of looking at this
which perhaps comes closer to Elioette's i-like-my-namespaces-explicit 
worldview. My last proposal assumes that the rules of namespace scoping 
should be modeled directly by the API and its implementation. It's 
perfectly possible to toss this assumption and get consistent and 
intuitive API behaviour. It goes something like this - 

All elements have an explicit namespace declaration. How that namespace
declaration is represented in the XML output is the business of the XML
outputter, in the JDOM (java object) representation, all elements
have explicit, immutable namespace declarations with no inheritence
or propagation rules. There are no distinguished namespaces such
as the default namespace  - the distinguished nature of the default
namespace is an artifact of the textual representation of XML belongs
in the java<->xml text conversion facilities and not in the core 
Java API. The intrinsic methods of element creation and lookup all
require an explicit namespace. All other variants of these methods are 
convenience methods with clearly documented semantics appropriate for
the particular method. 

What this all means - 

new Element("name") - create element in the empty namespace [no change]
  This is the only place a specific namespace is assumed and
  it is the empty namespace (xmlns="", if declared explicitly in XML
  text), for lack of any other sensible choice. If one
  wanted to be an anal purist, this constructor could simply be 
  removed. Users who need it could  write a trivial subclass 
  or trivial factory that provides this functionality. 

the namespace-less variants of get/remove child/children all use
the parent/receiver namespace as context. This is intuitive  - 
that's the only namespace they could possibly assume given that
all elements have a namespace and no namespace is special. If you're
asking an element for another element and provide no namespace, the
only sensible assumption the receiver can make is that you're asking
for something in _its_ namespace. This applies to the getCopy methods
and attribute related methods as well. The lack of 'default namespace'
semantics improves the conceptual simplicity of the API - in the case
of attirbutes, there is no need to explain that default namespaces
do not apply to attributes.

Aside for the changes in Element for  implicit lookup, outputters
would have to be modified to treat NO_NAMESPACE as the _empty_ as
opposed to the default namespace. The notion of a default namespace
would not exist in the JDOM. This approach has a certain appeal -
the complexity of the scoping rules is reduced and that makes sense
in an object model - you're navigating an instance graph and you can
easily ask any instance to tell you what it is. In other words, 
every Element already has a getNamespace() method, every Element
is already 'explicitly annotated' by virtue of the API. The 'default 
namespace' semantics are only useful when the XML is represented
as text, they can arguably help make the textual representation
more compact or more readable. An object model or a  Java instance 
graph has no such requirement. [A non-xml example of this is is the
representation of Java type names in source and at runtime, in a
particular piece of source a given type might be represented
as Foo, FooMaster.Foo or  com.fooborama.FooMaster.Foo, the
runtime only stores/cares about/tracks a stable, unique, FQ'ed name
that can be obtained for any instance of Foo by calling 
To use Jason Hunter's example again - 

// Create an element in the empty NS (or impossible if the constructor
// were removed entirely)
Element kid = new Element("kid");    

// Add the child...

// Retreieve the child

This would work iff parent were in the empty namespace as kid. It would 
not work if parent were in some other namespace. Is that a big deal? I
don't think it is. It may be a little confusing at first to people 
who are used to staring at a lot of XML text - but the API should cater
to Java programmers and present a consistent OO model - a model that 
allows accurate, deterministic, bidirectional conversion to XML but
is not burdened with every wart and detail of the textual 
representation. Chances are, as XML gains popularity, writing and
reading XML text manually will become a less-common chore and almost
all XML manipulation will be done programatically. It seems best to 
focus on programmatic representations that are sensible and easy 
for programmers to use at the cost of (when neccessary and possible)
of modelling  every of the textual representation.

What would the above changes mean for current code? 
If you're not using namespaces, everything works as it did before. 
If you are using namespaces, expecting some default behaviour other
than some assumption based on the namespace of the receiver is not
sensible. If you are using namespaces, you're best off being explicit
when instantiating (improves the maintainability of
the code anyway) and relying on the implicit lookup only when your
code has a strong built-in knowledge of the structure of the tags
its manipulating (usually the case). Potentially, a convenience
creation method could be added to Element for lazy typists

Element createChild(String name)
    Element newChild = new Element(name, namespace);
    return addContent(newChild);

As more and more systems employ XML, particularly for the purposes
of interoperability, namespaces become crucial. We're less 
likely to be seeing much code with no namespace use at all as time
goes on - namespace-capable JDOM code should be the assumed to be 
the default use-case. The simplicity and ease of writing and using 
namespace-capable code should take precedence i.e. if the API is
going to have convenience methods that make assumptions, those
assumptions should be such that make namespace-capable code easier
to write and use. 


More information about the jdom-interest mailing list