Internet Explorer XML/SVG自定义命名空间-生成额外/错误的命名空间

Internet Explorer XML/SVG自定义命名空间-生成额外/错误的命名空间,xml,internet-explorer,svg,Xml,Internet Explorer,Svg,我试图在网页中呈现一个SVG文档,然后通过JavaScript捕获该SVG文档的标记。然后将此SVG标记发送回服务器进行处理 我的SVG文档的根类似于以下内容: <svg id="layout" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:foobar="http://www.foobar.com" foobar:attribute="123abc"> 这

我试图在网页中呈现一个SVG文档,然后通过JavaScript捕获该SVG文档的标记。然后将此SVG标记发送回服务器进行处理

我的SVG文档的根类似于以下内容:

<svg id="layout" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:foobar="http://www.foobar.com" foobar:attribute="123abc">

这在Webkit和Firefox中运行得非常好,但是internetexplorer(像往常一样)会引起问题。当SVG在IE中呈现时,它看起来很好,但当我通过JavaScript/jQuery(XMLSerializer)获取其标记时,SVG字符串根节点现在看起来如下所示:

<svg xmlns="http://www.w3.org/2000/svg" id="layout" xmlns:NS1="" NS1:foobar:attribute="123abc" xmlns:NS2="" NS2:xmlns:foobar="http://www.foobar.com">

SVG得到了正确的显示,但是,正如您所看到的,当XML被序列化时,名称空间被弄乱了(属性被重新排列,但这并不是一个真正的问题)。这些混乱的名称空间破坏了处理提交的SVG字符串的服务器端代码。有人能解释一下发生了什么吗

我用谷歌搜索了一个下午,似乎找不到很多东西。我看到的所有例子都是人们试图通过JavaScript/jQuery添加名称空间,并得到与我看到的结果类似的结果(名称空间方面)

希望MSDN上的人知道发生了什么,我也打开了

编辑:添加了一些细节


编辑2:添加了指向MSDN线程的链接,我几乎建议在使用SVG时避免使用JQuery。您总是会遇到名称空间的问题

相反,尝试类似的方法

(new XMLSerializer()).serializeToString(document.querySelector("svg"))

如果您可以让XMLSerializer为您一致地工作,那么这绝对是一条正确的道路。我以前遇到过这个问题,之所以会出现这个问题,是因为我使用jQuery将SVG内容添加到页面中。当我从字符串中读取内容并使用标准appendChild方法添加内容时,我确保使用了
new DOMParser().parseFromString(content,'text/xml')
来消除它

但是,我发现,在几种不同的浏览器实现中,特别是在较旧的IE和Safari版本中,存在一些怪癖,如果您有自定义名称空间的内容,那么使用它们会很困难。如果您做得不好,名称空间将被剥离或损坏,正如您所看到的

我最终放弃了,自己编写了一个简单的程序,可以跨所有浏览器正确处理名称空间。YMMV,但它对我使用的内容非常有效

function serializeSvgContent(element) {
  var result = '<' + element.nodeName;

  // add in the element's attributes
  for (var i = 0; i < element.attributes.length; i++) {
    var attribute = element.attributes[i];
    var name = attribute.name || attribute.nodeName;
    var value = (attribute.value || attribute.nodeValue).replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;')
      .replace(/'/g, '&apos;');
    result += ' ' + name + '="' + value + '"';
  }

  if (element.childNodes.length > 0) {
    result += '>';

    // recursively add any child elements
    for (i = 0; i < element.childNodes.length; i++) {
      var child = element.childNodes[i];
      if (child.nodeType === 1) {
        result += serializeSvgContent(child);
      }
    }
    result += '</' + element.nodeName + '>';

  } else {
    result += '/>';
  }
  return result;
}
函数序列化svgcontent(元素){
变量结果='0){
结果+='>';
//递归地添加任何子元素
对于(i=0;i
您是如何进行序列化的?嗯……我刚刚用jQuery通过$('.selector').html()获取了它,但似乎这就是名称空间问题的症结所在。IE中的页面源具有适当的名称空间声明,但当我尝试获取标记时,它会被破坏。我已经尝试了所有我能想到的从页面获取标记的方法,但似乎都打破了它……我也尝试了直接的JavaScript,它也返回了混乱的名称空间。我认为问题一定出在IE的XMLSerializer实现中?好的,您是如何在foobar名称空间中生成属性的?在我的测试设置中,整个SVG标记与页面的其余部分一起发送到客户端。在“真实”代码中,SVG将通过Ajax调用发送,并插入页面。