[jdom-interest] Accessing Child Elements

Peter V. Gadjokov pvg at c-c-s.com
Wed Sep 6 11:31:27 PDT 2000


 
There was another thread of discussion (under the 'API instability')
subject that went over this, I'd omitted to catch up with all the
traffic when I sent out my mail...

One of the issues was described by the following example by Jason
Hunter:

>To argue against myself and with Elliotte, another problem with 
>getChild("child") using the parent's namespace is that 

>Element kid = new Element("kid"); 
>parent.addContent(kid); 
>parent.getChild("kid"); 

>*wouldn't work* if the parent was in a namespace.  That's pretty 
>confusing.  With the current code it would work because kid would be in

>no namespace.  

It's been said that a JDOM tree can be unvaildated, badly formed and in
all sorts of intermediate states - this is undoubtedly useful,
programatically, but at the same time the classes and objects making up
the api have to represent something beyond 'an oddly constrained
tree/digraph with funny node names' so some contracts have to be
enforced and some amount of useful default behaviour has to be provided.
Doing this and keeping the API simple, flexible and easy to understand,
getting the balance right, can be quite tricky (and contentious and
fun).  

I'd argue that the current code 'works' but is wrong. It works well
enough for outputting the XML and getting the correct namespace scoping
but it doesn't _model_ the way namespaces actually work and that's
what's confusing. 
Element.getNamespace() should tell you what namespace an element is
_currently_ in, a new method is needed to query the namespace an element
was explicitly declared in. I think the following semantics would be
'intuitive':

- elements are instantiated in the default namespace when no namespace
  is given [no change]
- a new method is added to Element
    public Namespace getDeclaredNamespace();
  this would return the namespace the element was declared in, in JDOM,
  this declaration is immutable so it would return the namespace the
  Element was created with. 
- if an element is in the default namespace getNamespace should
  recursively find the enclosing explicitly declared namespace by
  walking up the tree. This models the way namespaces are 'lexically  
  scoped' in XML. 
- element.getChild(Element name) returns the element in the current
  enclosing namespace. It has to handle three success cases - 
  both parent and  child are in the default namespace, parent has
  an explicitly declared namespace while the child is in the default
  and (somewhat twisted) the parent is in-scope of some namespace
  declared 'above' it and the child has the same namespace but it's 
  declared explicitly. This sounds convoluted but if getNamespace()
  were modified as described above, the changes to getChild involve
  a simple addition of a call to getNamespace()

So, to walk through Jason's example - 


Element kid = new Element("kid"); // kid created, it is now in the def.
                                  // ns. and declared in the def. ns. 

// kid.getNamespace() should return default namespace
// as should kid.getDeclaredNamespace()

parent.addContent(kid);           // kid is added, neither element is 
                                  // modified other than setting up 
                                  // parent-child references but 
                                  // kid  should now be in 
                                  // the namespace of the parent. 

// kid.getNamespace().equals(parent.getNamespace())
// should return true, as should an identity comparison
// == since namespaces are uniqued
// kid.getDeclaredNamespace() should still return the default 
// namespace, no matter what getNamespace() returns now

parent.getChild("kid");            // kid is returned, since it is
looked
                                   // up in the namespace returned by
                                   // parent's getNamespace() call. 

// the kid essentially gets looked up by a getChild implementation in
// the parent that looks something like
// return getChild(kidName, getNamespace());


Comments?

-pvg

-----Original Message-----
From: David W. Smiley
To: Peter V. Gadjokov
Cc: jdom-interest at jdom.org
Sent: 9/6/00 7:30 AM
Subject: RE: [jdom-interest] Accessing Child Elements

...
>If the implementation were changed to:
> 
> public Element getChild(String name)
> {
>     return getChild(name, namespace); // use the enclosing namespace
> }
> 
> the behaviour in the for the no-namespaces-used remains the same as it
> is now and something more sensible is returned when namespaces are in
> use.
...

Sounds great to me!  Hard to disagree with this change.

-- David Smiley

_______________________________________________
To control your jdom-interest membership:
http://lists.denveronline.net/mailman/options/jdom-interest/youraddr@you
rhost.com

-----Original Message-----
From: David W. Smiley
To: Peter V. Gadjokov
Cc: jdom-interest at jdom.org
Sent: 9/6/00 7:30 AM
Subject: RE: [jdom-interest] Accessing Child Elements

...
>If the implementation were changed to:
> 
> public Element getChild(String name)
> {
>     return getChild(name, namespace); // use the enclosing namespace
> }
> 
> the behaviour in the for the no-namespaces-used remains the same as it
> is now and something more sensible is returned when namespaces are in
> use.
...

Sounds great to me!  Hard to disagree with this change.

-- David Smiley

_______________________________________________
To control your jdom-interest membership:
http://lists.denveronline.net/mailman/options/jdom-interest/youraddr@you
rhost.com



More information about the jdom-interest mailing list