具有 xmlns 的元素与使用具有相同 namespaceURI 的 createElementNS 创建的元素有何不同?

问题描述

假设我们有以下 XML:

<ns:xml xmlns:ns="AAA">
  <predefined xmlns="AAA"/>
</ns:xml>

在浏览器中运行以下代码时:

const doc = new DOMParser().parseFromString(XML,'text/xml');

const added = doc.createElementNS('AAA','added');
doc.documentElement.appendChild(added);

只是序列化 added 返回 <added xmlns="AAA"/> 但是当序列化 doc 时,结果是

<ns:xml xmlns:ns="AAA">
  <predefined xmlns="AAA"/>
  <a:added />
</ns:xml>

为什么 predefinedadded 的行为不同? 或者反过来问: 我如何能够使用 predefined(和其他 DOM API)创建像 createElementNS 这样的元素?

解决方法

要使 added 表现得像 predefined,您需要将 xmlns 属性显式设置为与 namespaceURI 参数相同的命名空间:

const added = doc.createElementNS('AAA','added');
added.setAttribute('xmlns','AAA');
doc.documentElement.appendChild(added);

另请注意,使用 mime 类型 text/html 对其进行解析会更改(解析和)序列化的行为,从而导致以下结果:

<ns:xml xmlns:ns="AAA">
  <predefined xmlns="AAA"></predefined>
  <added xmlns="AAA"></added>
</ns:xml>