[jdom-interest] First pass at Namespace revision[eg]

GB/DEV - Philip Nelson philip.nelson at omniresources.com
Fri Mar 9 14:08:15 PST 2001


I have been writing tests for Namespace, have been reviewing a couple user
problems and reading the JDOM docs and I have a few proposals for changing
Namespace and a related minor change in XMLOutputter.  I am now +1 on
removing the Attribute(String, String, String, String) constructor).  I have
moved solidly on the side of having == mean the uri == uri as opposed to
prefix+uri == prefix+uri and .equals meaning the same thing but I am not
proposing a change just yet on that.  

#1
The first one is easy.  In getNamespace(prefix, uri), before any checking of
the prefix and uri there is:

		// Return existing namespace if found
		if (namespaces.containsKey(uri)) {
			return (Namespace)namespaces.get(uri);
		}

The only time this would ever find anything is for the special case uri = ""
because stored mappings are keyed as prefix&uri.  So let's just return
Namespace.NO_NAMESPACE in this case.

#2
Another Namespace change would be a simple test in getNamespace() that
throws an error if a prefix is provided but the uri is "" which should not
be allowed but happily succeeds now. You can also add multiple default
namespaces to an element with this trick :^(.  This Namespace change won't
fix all the problems but it is a start.

#3
Finally, here is a little more of an api change.  The NO_NAMESPACE namespace
is identified as a namespace that represents nothing.  However, I think a
distiction needs to be made between "the element has no namespace" and "the
element has an empty namespace"

These are now equivalent in JDOM and what I *think should happen* doesn't
happen.  Here is an example (c/o Jochen Strunk)

Element element = new Element("element",
Namespace.getNamespace("http://foo"));
Element child1 = new Element("child1");
Element child2 = new Element("child2");

element.addContent(child1);
element.addContent(child2);

XMLOutputter op = new XMLOutputter("     ", true);
op.output(element, System.err);

It outputs:
<element xmlns="http://foo">
      <child1 xmlns="" />
      <child2 xmlns="" />
</element>

In my opinion this is incorrect, the correct output would be:
<element xmlns="http://foo">
      <child1 />
      <child2 />
</element>

It is possible to get the correct output by adding the full default
namespace of the parent to the children.  However a much more elegant
solution IMHO is to add another static final to Namespace called
EMPTY_NAMESPACE.  Then in XMLOutputter, you can test against the namespaces
and correctly do either output example above simply by choosing which of the
namespaces is appropriate.

for children with an explicit empty namespace:
Element child1 = new Element("child1", Namespace.EMPTY_NAMESPACE);
Element child2 = new Element("child2", Namespace.EMPTY_NAMESPACE);

The NO_NAMESPACE variant works like you would expect it to and would be the
default:
Element child1 = new Element("child1");
Element child2 = new Element("child2");

element.addContent(child1);
element.addContent(child2);

<element xmlns="http://foo">
      <child1 />
      <child2 />
</element>

I have made a working and lightly tested version of this, though my original
tests still worked on the new version.  The XMLOutputter change is very
minor.  My Namespace changes are a little more involved, but I will hold off
on details until I hear that people think this is a good idea.  I think
these changes are required to be able to easily and naturally create the
examples given in the xml-names specs from the w3c.





More information about the jdom-interest mailing list