No subject

Fri Aug 6 17:04:17 PDT 2004

and dry - a caller is sends a message to an instance, explicitly
omitting a usually-required parameter and asking the message receiver
to fill in the blank with something that can be reasonably expected.
What does the receiver do - a) fills in the blank with well-defined,
instance-intrinsic data or b) fills in the blank with some externally
mandated, hardcoded magic value. I've argued above that the magic is
not useful. Even if we agreed it is somewhat useful in some cases, the
value of eliminating magic from an API should override the
'occasionally useful' objection. The no-magic implementation is a true
composite convenience method - it can be implemented externally in
terms of intrinsic methods without any knowledge of what assumptions
the receiver might be making internally. The magic (no-namespace)
version is not - the caller is expected to share the awareness of a
special constant which cannot be obtained by querying the receiver.

>A large part of the issue is that, unlike DOM, JDOM allows elements 
>to exist and be moved and copied and so forth independent of a 
>document or context. To allow namespaces to be context dependent 
>would mean that an element could change from an RDF set element to an 
>SVG set element to a MathML set element simply depending on where it 
>was put. This is not what users need or want.

I personally can't speak for other users needs and wants but I
wholeheartedly agree that the context-dependent elements are a more
complex and less coherent design approach.

>I understand not all the proposals involve context dependent 
>namespaces. Some simply want a request for children to assume the 
>namespace of the parent. However, I still don't like this. In the 
>general case, I may not know the namespace of the parent. For 
>instance, I could be walking a document tree looking for all svg 
>elements in the namespace. I don't know where 
>those will show up. Or looking for all title elements with no 
>namespace. In either case I should ask for exactly what I want. I 
>think making the behavior of the getChild(String name) method 
>dependent on the namespace of the parent element will be confusing 
>for many users and cause unexpected bugs.

In the general case, one would not be using the convenience method.
The convenience method is there because a) it simplifies a very common
operation b) it's behaviour is trivial to explain and understand.

Let's run with the svg example for a bit. You have some document that
contains all sorts of data out of which you are interested in
extracting and operating on svg elements. You traverse the tree, using
the intrinsic method to explicitly find elements in the svg
namespace(s). Once you find them, you can continue to use the
intrinsic method to extract and interpret the well-defined (i.e.
you're either implementing the svg java-binding on top of JDOM or
you're custom-coding the subset of svg you need in your need - in
either case, your app is aware of and encodes some or all of svg's
structure and semantics) sub-elements OR you save yourself some typing
(hence 'convenience method') and simply use getChild(name). You don't
have to, if you prefer to be explicit throughout, sure, but where in
this entire use-case would you find a use for a getChild(name) method
that gives you a child element from the empty namespace? Ok, the svg
elements might contain some embedded elements from a foreign namespace
- according to the SVG spec, typical use cases for this are
app-specific data or 'supplemental extensibility data'. Only the
former has any chance of being in the empty namespace and even then,
such a use would be rather questionable data-representation design.
Incidentally, the example given in the spec has application-specific
model data with well-defined, nonempty namespace.
>I think the current approach is simpler, more intuitive, easier to 
>explain and easier to learn. This is,
>1. An unprefixed name with a URI is always in the default namespace.
>2. An unprefixed name without a URI is always in no namespace.
>3. A prefixed name is always in whatever namespace the URI specifies.
>Note that these rules are true for ALL methods in ALL classes. There 
>are no special cases, or instances where the rules change depending 
>on which method you're calling. This is consistent, and therefore 
>easy to learn and easy to use. What's being proposed is much less 
>consistent, much less easy to learn, and much less easy to use.

I disagree, partially because I'm not done proposing :) The above
rules are not complex but they are no simpler than mine and I believe
they represent less-useful semantics. But let's assume for a minute
that's all a matter of taste. The next logical step, in my mind, is to
excise the notion of prefix (and by extension, FQN) from the core
model classes (Namespace, Element, Attribute) - which is why my
proposal was so adamant about eliminating the notion of a default
namespace. Why would one want to do that? Because prefixes are an
artifact of the encoding, in fact, not even the encoding but a
particular encoded instance of a particular document or document
fragment. They are entirely useless to the user of the object model
and therefore do not belong there - the mapping of namespaces to local
prefixes should certainly be expressed somewhere - external to the
core model classes but accessible to the encoding/decoding facilities.
If this is done, the core api becomes much simpler and much more
intuitive - a messy and irrelevant concept has been removed and
replaced by something much cleaner (an object representation of what
Appendix A of the namespace spec calls Expanded Element|Attribute
types). Conceptually, at the object level, neither namespaces,
elements nor attributes have prefixes. Elements and attributes belong
to namespaces and namespaces are uniquelly identified by URI and URI
alone. Elements and attributes have stable (unlike FQNs, and much more
appropriate for an API that wants to allow easy mobility of elements
from one document to another), object-encapsulated,
standard-externalizable (via the encoding in the previously mentioned
appendix or others) type identifiers which:

- raise the abstraction level of the api to the use it is trying to
  represent (find me theelement or attribute of well-defined type X)

- allow and encourage more maintainable code - no more hardcoded
  element.getChild,"magic", someNSInstanceWithSomethingCalledAPrefix)

- simplify the implementation of 'configurable' parsing/manipulation,
  particularly, performing a 'move to another document, transform type
  and maintain structural equivalence' which some users seem to want.

- simpler, more readable api
  element.getChild(SVG_ANIMATE_ELEM); // use external, reusable const
  vs one of
  someElement.getChild("animate", theSVGNamespace);

Namespaces, Element- and AttributeExpandedTypes become first-class,
document-independent, comparable (quicky, by identity (==) should we
choose to internalize and unique them - they are very suitable to for
this as they are global and immutable), 'context unburdened' objects.
They help hide details of the encoding irrelevant to the OO API user
and promote simpler, more readable, maintainable, faster code. They
make being explicit and unambiguous (something you want) when
retrieving typed subnodes easy, intuitive and clearly abstracted
(somethign I want).

The last bulleted example also shows a way out of the 'default
behaviour of the getChild(name) convenience method' debate - if we
have stable type identifiers, we need neither the name, namespace
method nor its name-only variant.

I'd like to implement something like this, whether as part of JDOM or
not - but I think it would help JDOM achieve its stated goals. I'd be
happy to hear any counter-arguments, the ones that I find most
relevant are:

   'An interesting idea, appropriate form JDOM but not now because...'
   'An interesting idea but not approproate for JDOM because...'
   'A naive idea which is unimplementable because of XML reason...'(*)
   'A naive idea which is unimplementable because of JDOM/Java
   'An outright wrong idea because of reason/usecase/requirement X you
    have not considered at all which is...'

(*) Even if it turns out this does not fit in JDOM, I'd be interested
and grateful to hear any such objections anyway, particularly from
broad XML experts such as Elliotte.


P.S. Still reading? That's the lot of it, really. Responses wellcomed
even if they are much shorter than the original.

------ =_NextPart_000_01C018E2.24041D50
Content-Type: application/octet-stream;
Content-Disposition: attachment;

------ =_NextPart_000_01C018E2.24041D50--

More information about the jdom-interest mailing list