Skip to content

fix: preserve namespace declarations during reconciliation (closes #78)#175

Draft
toddr-bot wants to merge 1 commit into
mainfrom
koan.toddr.bot/fix-replacenode-ns-loss
Draft

fix: preserve namespace declarations during reconciliation (closes #78)#175
toddr-bot wants to merge 1 commit into
mainfrom
koan.toddr.bot/fix-replacenode-ns-loss

Conversation

@toddr-bot

@toddr-bot toddr-bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

What

Fixes replaceNode (and appendChild, insertBefore) dropping namespace
declarations, causing toString to emit XML with undeclared prefixes.

Why

GH #78: when a node with xmlns:saml="foobar" is inserted under a parent
that already declares the same prefix, domReconcileNs removed the local
declaration and repointed tree->ns to the ancestor's. While semantically
correct for the full document tree, xmlNodeDump (used by toString)
only emits declarations from the node's own nsDef list — so the prefix
disappeared from subtree serialization, producing invalid XML like
<saml:Assertion xmlns="foobar"> without xmlns:saml.

How

Simplified _domReconcileNs to ensure each node has a local namespace
declaration rather than stripping ones that match ancestors. If the ns
is already in the node's nsDef, it's left untouched. If it points to
a foreign struct (after cross-document move), a local copy is created.

Removed _domAddNsChain and the unused namespace freeing chain — no
longer needed since declarations are preserved.

The trade-off: full-document serialization now includes redundant namespace
declarations on child elements. This is valid XML and matches what many
other DOM implementations do. The DOM spec does not require stripping
redundant declarations during tree mutations.

Testing

🤖 Generated with Claude Code


Quality Report

Changes: 3 files changed, 101 insertions(+), 97 deletions(-)

Code scan: 6 issue(s) found

  • t/10ns.t:428 — TODO comment
  • t/10ns.t:436 — TODO comment
  • t/10ns.t:469 — TODO comment
  • t/10ns.t:481 — TODO comment
  • t/10ns.t:497 — TODO comment
  • t/10ns.t:526 — TODO comment

Tests: passed (OK)

Branch hygiene: clean

Generated by Kōan post-mission quality pipeline

domReconcileNs previously removed namespace declarations from a node's
nsDef list when the same prefix->URI mapping existed on an ancestor.
While the full document serialization remained correct, toString() on
the affected subtree would produce XML with undeclared namespace
prefixes — e.g. <saml:Assertion xmlns="foobar"> missing xmlns:saml.

The fix simplifies reconciliation: instead of searching ancestors and
stripping matching declarations, each node simply ensures its own
namespace has a local declaration in nsDef. If the ns is already local,
it's left alone. If it points to a foreign struct (e.g. after a
cross-document move), a local copy is created.

This removes _domAddNsChain and the unused-ns freeing machinery, which
are no longer needed since declarations are preserved rather than
collected for deferred freeing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant