使用javascript在xml序列化期间避免重复名称空间

使用javascript在xml序列化期间避免重复名称空间,javascript,xml,dom,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

下面的代码

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>

了解了如何通过使用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));
var parser=new DOMParser(),
s=新的XMLSerializer(),
dom1=parser.parseFromString(“”,'text/xml'),
dom2=parser.parseFromString(“”,'text/xml'),
myElm=dom2.createElements('hello-world','ns3:Inner');
dom2.documentElement.appendChild(myElm);
dom2.documentElement.attributes.removeNamedItem('xmlns');
dom1.documentElement.appendChild(dom2.documentElement);
log(s.serializeToString(dom1));
这将在Chrome(mac上为26.0)、Firefox(mac上为21.0)和Opera(mac上为12.15)中输出以下xml——尽管Opera还包含xml声明,这可以满足我的需要



最坏情况:s.serializeToString(outer).split('xmlns=“hello:world1”).join('')@dandavis不起作用,因为节点缺少指示该节点不同命名空间的“ns1:”前缀。如果两者都使用ns1,则不需要对内部标记进行命名空间设置。此外,您不能像那样设置命名空间内部属性,请使用setAttributeNS和createElementNS。谢谢您的评论!在本例中,名称空间是不同的——因此这很重要(示例tho中未显示外部名称空间)。对于setAttribute上的setAttributeNS:setAttributeNS,当属性名称为'xmlns:ns1'(“NamespaceError:DOM Exception 14”)时,将导致错误。这个错误实际上可能与浏览器复制名称空间的原因有关,但这也是rational for me发布问题的一部分。。。我是否应该使用另一个API来防止重复的名称空间声明,并将定义移动到更高的共享节点,就像我在上一个xml片段中所做的那样。
<doc xmlns="one">
  <outer xmlns:ns3="hello-world">
    <ns3:Inner/>
  </outer>
</doc>