Skip to content

Error thrown when resetting the default namespace to null on a prefixed element #48

Open
@bwrrp

Description

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":

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.

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions