default attributes and namespaces

Hi there,

I'm confounded by the interaction between namespaces and default
attributes, where these default attributes have prefixes.

I've been hunting the DOM lvl 2 recommendation for information on this,
and so far I've not been able to find a lot on this.

First the story as far as I understand it:

Default attributes are declared in the DTD (often in the internal
subset). DTDs are not namespace aware (I realize XML schema are,
but I'm not focusing on these for now). You can use prefixes in the
DTD however, so you could create the prefixed default attribute
myprefix:foo.

In the document, there may be a namespace declaration associating 
'myprefix' with some namespace URI. The default attribute with this prefix
can then appear for some element node in the scope of that declaration
and will then be put in that namespace. If a default attribute with 'myprefix'
appeared outside the scope of any declaration associating this prefix with
a namespace URI, this is an error.

The problem:

We have some prefixed default argument like: 'myprefix:foo'. Let's say this
applies to all 'bar' elements. Now we create such an element. What happens?
Is this an error, as 'myprefix' has no meaning in the context of that
element yet? What if we did a 'removeAttributeNS' or 'removeNamedItemNS'
on some existing document, however? The default attribute would appear,
but would it take on a namespaceURI if the prefix was known in the
scope? That would introduce a whole lot of namespace scoping rules into the
DOM spec which it doesn't need for anything else, as normally namespace URIs
are explicitly associated with elements and attributes, so that doesn't
seem right.

Now to the DOM and some of the clues I found:

The 'createElement' method says this:

  In addition, if there are known attributes with default values, Attr
  nodes representing them are automatically created and attached to the
  element.

No explanation of what would happen if such an attribute had a namespace
prefix, though.

'createElementNS' does not give any further information.

The 'prefix' attribute of the Node interface seems to confirm the
philosophy of the DOM; the prefixes aren't the real namespaces (as
the namespace spec already says), and no scoping rules are necessary,
as namespaceURIs are always associated with Nodes anyway, and those
don't change if you change the prefix.

'removeNamedItemNS'

  Removes a node specified by local name and namespace URI. A removed
  attribute may be known to have a default value when this map contains the
  attributes attached to an element, as returned by the attributes attribute
  of the Node interface. If so, an attribute immediately appears containing
  the default value as well as the corresponding namespace URI, local name,
  and prefix when applicable.

'corresponding', to what? Corresponding as defined in the DTD or schema,
or taking the same namespace URI, local name, and prefix as already 
defined on the attribute just removed? Will an attribute in a namespace
never have a default value in a DTD at all, or is it dependent on prefix
and localName in the DTD or perhaps just on localName?

If the prefix of the default attribute plays a role on whether something
happens, that would pull in a lot of namespace scoping rules, which
I presume the DOM doesn't want to do.

The same questions apply to 'removeAttributeNS':

  Removes an attribute by local name and namespace URI. If the removed attribute
  has a default value it is immediately replaced. The replacing attribute has 
  the same namespace URI and local name, as well as the original prefix.

The original prefix of the attribute just removed, or a prefix defined
by the DTD? Again, if the DTD just defines the name of the default
attribute, would it apply here?

You could say that since DTDs don't define default attributes in namespaces
at all, they can never appear when creating an Element or when removing
existing attributes that are in a namespace. A prefixed default attribute
would just get the prefix in the nodeName, just like createAttribute() would
do if you fed it 'foo:bar' for the name (would it do that?).
Of course that would be somewhat inconsistent with the scenario without
DOM that I sketched above, but it seems like a reasonable solution.

Is that the real story? 

Thanks,

Martijn

Received on Thursday, 25 October 2001 20:20:32 UTC