Description
While revisiting the XML serialization spec I found a few more bugs in it that can lead to serialization issues:
prefix redeclaration confusion
const root = document.appendChild(document.createElementNS('ns1', 'pre:root'));
const child = root.appendChild(document.createElementNS('ns2', 'pre:child'));
child.appendChild(document.createElementNS('ns1', 'grandChild'));
This currently results in grandChild
being assigned the pre
prefix without redeclaring it, which places it in ns2
instead of ns1
.
Firefox assigns a new a0
prefix to child
here to avoid this. Chrome redeclares the pre
prefix on grandChild
back to ns2
.
Chrome's behavior seems to more closely match the author's intent in that it preserves all prefixes as specified. To match that, the algorithm should likely keep track of the prefix to namespace mapping in addition to the currently tracked inverse mapping, and use that to check if the prefix it wants to use needs to be redeclared.
generated prefix collisions
const root = document.appendChild(document.createElementNS('ns1', 'ns1:root'));
root.setAttributeNS('ns2', 'attr', 'value');
This currently results in two declarations for the ns1
prefix on the root
element, one for ns1
produced as part of serializing the element, one for ns2
produced for the generated prefix ns1
. That is not well-formed.
Firefox and Chrome both assigns a new prefix to attr
here to fix this. In Firefox the prefix is a0
, Chrome uses ns2
.
To fix, the "generate a prefix" algorithm should probably check whether the prefix it intends to generate isn't declared already. If there is an existing local declaration for the prefix, it can loop to try a higher prefix index
, matching Chrome's behavior.
Activity