使用javascript避免在xml序列化期间复制命名空间

时间:2013-05-21 19:31:45

标签: javascript xml dom

以下代码

var ns1 = 'hello:world1',
    doc = document.implementation.createDocument('nsdoc', 'doc', null),
    outer = doc.createElement('outer'),
    s = new XMLSerializer(),
    elm;

outer.setAttribute('xmlns:ns1', ns1);
elm = doc.createElementNS(ns1, 'Inner');

outer.appendChild(elm);

console.log(s.serializeToString(outer));

以chrome和firefox输出以下xml文档。

<outer xmlns:ns1="hello:world1">
  <Inner xmlns="hello:world1"/>
</outer>

虽然这在技术上仍然有效,但有没有办法删除重复的ns声明,或者是否有更好的api用于在父节点上设置命名空间以供在子节点中使用?例如,文档最好如下所示:

<outer xmlns:ns1="hello:world1">
  <ns1:Inner/>
</outer>

1 个答案:

答案 0 :(得分:0)

弄清楚如何通过使用DOMParser和一些不舒服的手写XML(但仅针对根节点)更好地控制命名空间的序列化方式。以下javascript做到了这一点:

var parser = new DOMParser(),
    s = new XMLSerializer(),
    dom1 = parser.parseFromString('<doc xmlns="one"></doc>', 'text/xml'),
    dom2 = parser.parseFromString('<outer xmlns="one" xmlns:ns3="hello-world"></outer>', 'text/xml'),
    myElm = dom2.createElementNS('hello-world', 'ns3:Inner');

dom2.documentElement.appendChild(myElm);
dom2.documentElement.attributes.removeNamedItem('xmlns');
dom1.documentElement.appendChild(dom2.documentElement);
console.log(s.serializeToString(dom1));

这将在Chrome中输出以下xml(mac上为26.0),Firefox(Mac上为21.0)和Opera(Mac上为12.15 - 虽然Opera也包含xml声明,可以满足我的需求)

<doc xmlns="one">
  <outer xmlns:ns3="hello-world">
    <ns3:Inner/>
  </outer>
</doc>