[w3c/DOM-Parsing] Error thrown when resetting the default namespace to null on a prefixed element (#48)

Consider the following code, run on an empty XML document:

```
const root = document.appendChild(document.createElementNS('ns_root', 'root'));
const child = root.appendChild(document.createElementNS('ns_child', 'p:child'));
child.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', '');
const grandChild = child.appendChild(document.createElementNS(null, 'grandchild'));
```

Which produces the following DOM (whitespace added for clarity):

```
<root xmlns="ns_root">
  <p:child xmlns:p="ns_child" xmlns="">
    <grandchild/>
  </p:child>
</root>
```

If we now run the serialization algorithms as specified, with the `require-well-formed` flag set (as would be the case in `root.outerHTML`, for instance), an exception is thrown at step 3.5.2.3. of "[serializing an element's attributes](https://w3c.github.io/DOM-Parsing/#serializing-an-element-s-attributes)":

> If the `require well-formed` flag is set (its value is `true`), and the value of `attr`'s `value` attribute is the empty string, then throw an exception; namespace prefix declarations cannot be used to undeclare a namespace (use a default namespace declaration instead). 

The error message seems to suggest that this check is intended only for prefix declarations, and indeed something like `xmlns:pre=""` would have been invalid. However, setting the default namespace back to null should be allowed. In the example given, an explicit declaration on child would be preferable to having an automatically generated `xmlns=""` on `grandchild`, especially in cases where there would be many `grandchild` nodes. 

It seems that the condition for this error should have included a check whether `attr`'s `prefix` attribute is not null. Note that both default namespace declaration attributes and prefix declaration attributes are specified to be in the XMLNS namespace, even though the former does not have a prefix (this is the only case of an unprefixed attribute having a non-null namespace).

Note that this case is only hit for an `xmlns=""` declaration on an element that is itself prefixed, in a namespace other than the inherited default. If the element itself is unprefixed it would itself be in the null namespace. This would cause its own serialization generating the declaration and the `ignore namespace definition attribute` flag being set for the call to serialize its attributes, which in turn would cause the algorithm to skip the attribute earlier at step 3.5.2.1. (second bullet point).

Testing the above example in Firefox and Chrome shows that `root.outerHTML` returns the expected serialization (minus the whitespace) and does not throw the error.

Please let me know if it would be appreciated if I submit a PR (here and/or on the WPT repo?). It looks like the last one was flagged as I'm not a W3C member.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/w3c/DOM-Parsing/issues/48

Received on Friday, 22 March 2019 09:53:56 UTC