如何使用Javascript删除XML命名空间?

8
我发现,对于我的需求来说,XML命名空间只会带来很多麻烦,并且完全没有必要。(例如,它们如何使xpath变得复杂。)
有没有一种简单的方法可以从XML文档中完全删除命名空间?
(有一个相关的问题,但它涉及删除标记上的命名空间前缀,而不是从文档根中删除命名空间声明:“使用javascript轻松删除XML命名空间的方法”。)
编辑:下面是示例和更多详细信息:
XML:
<?xml version="1.0" ?>
<main xmlns="example.com">
  <primary>
    <enabled>true</enabled>
  </primary>
  <secondary>
    <enabled>false</enabled>
  </secondary>
</main>

JavaScript:

function useHttpResponse()
{
    if (http.readyState == 4)
    {
        if(http.status == 200)
        {
            var xml = http.responseXML;
            var evalue = getXMLValueByPath('/main/secondary/enabled', xml);
            alert(evalue);
        }
    }
}

function getXMLValueByPath(nodepath, xml)
{
    var result = xml.evaluate(nodepath, xml, null, XPathResult.STRING_TYPE, null).stringValue;
    return result;
}

示例XML与我实际使用的XML非常相似,尽管长度要短得多。请注意,标签上没有命名空间前缀。我认为这是空或默认命名空间。
JavaScript是我的ajax函数中的片段。如果我从main标记中删除xmlns="example.com"部分,则可以成功获取值。只要存在任何命名空间,该值就变为未定义。
编辑2:
可能值得一提的是,在XML标记中没有使用任何已声明的命名空间(如上面的示例)。在我正在处理的实际XML文件中,声明了三个命名空间,但没有任何标记带有命名空间引用。因此,也许问题应该重新命名为“如何使用JavaScript删除未使用的XML命名空间?”如果它既未被使用又使使用xpath查找节点变得复杂,那么我不认为保留命名空间有任何意义。

这里的讽刺是,名称空间显然是为了允许重复的标签并避免它们之间的混淆而开发的。我有不同父标记的重复标记,并尝试使用xpath来选择它们。如果我手动删除命名空间声明,选择元素就很简单。但是,如果命名空间声明完整存在,它将完全失败。 - JYelton
2
为什么不寻求使用命名空间的帮助,而要放弃呢? - John Saunders
命名空间不应该特别复杂化xpath,你只需要在xpath内部的部分加上命名空间即可。也许弄清楚为什么你的xpath不起作用比剥离结构数据更好? - Erica
但它处理的是从标签中删除命名空间,而不是从整个文档中删除。您能解释一下区别吗?您是要删除命名空间声明吗?命名空间前缀?除了从标记中删除它们之外,从整个文档中删除命名空间是什么意思? - LarsH
沿着@John Saunders所说的方向,如果您发布输入XML和失败的XPath以及尝试使用XPath的javascript代码,我们可能可以帮助您成功地处理命名空间。是的,在您了解如何使用之前,它们可能很难处理。但是,与其对抗,它们也是一种痛苦。 - LarsH
显示剩余15条评论
3个回答

6
这应该会删除您找到的任何命名空间声明:
var xml = http.responseXML.replace(/<([a-zA-Z0-9 ]+)(?:xml)ns=\".*\"(.*)>/g, "<$1$2>");

在Javascript控制台中出现错误:http.responseXML.replace不是一个函数 - JYelton
@JY:在调用replace()方法之前,您可以将responseXML转换为字符串来强制使其工作。但这并不是很健壮,因为您并没有真正解析XML。@andre:您确定那个正则表达式是正确的吗?您能解释一下[a-zA-Z0-9 ]+是什么意思吗? - LarsH
那个正则表达式是正确的。你提到的部分只是获取标签名称和后面的空格,所以在 <rootnode xmlns="some.domain.name" attribute="value"> 中,它会被替换为 <rootnode attribute="value"> - Andre
@LarsH:将其转换为字符串肯定是一种选择,以使替换函数起作用。但是,它需要被转换回XML。我需要关于如何做到这一点的建议(使用某种字符串解析重新创建XML文档?)。 - JYelton
可能希望在“responseText”而不是“responseXML”上执行替换(保存转换)。但仍需要将其加载到XML文档中才能发挥作用。肯定有更好的方法。 - Hemlock
显示剩余2条评论

4
为了替换一个XML javascript字符串中所有的xmlns属性,您可以尝试以下正则表达式。
xmlns=\"(.*?)\"

注意:此正则表达式可用于替换任何属性。

var str = `<?xml version="1.0" ?>
<main xmlns="example.com">
  <primary>
    <enabled>true</enabled>
  </primary>
  <secondary>
    <enabled>false</enabled>
  </secondary>
</main>`;

str = str.replace(/xmlns=\"(.*?)\"/g, '');

console.log(str)


0

不使用正则表达式的方法(这也可以移除属性)

let xml = '';//input
let doc = new DOMParser().parseFromString(xml,"text/xml");
var root=doc.firstElementChild;
var newdoc = new Document();
newdoc.appendChild(removeNameSpace(root));
function removeNameSpace (root){    
    let parentElement = document.createElement(root.localName);
    let nodeChildren = root.childNodes;
    for (let i = 0; i <nodeChildren.length; i++) {
        let node = nodeChildren[i];
        if(node.nodeType == 1){
            let child
            if(node.childElementCount!=0)
                child = removeNameSpace(node);
            else{
                child = document.createElement(node.localName);
                let textNode = document.createTextNode(node.innerHTML);
                child.append(textNode);
            }
            parentElement.append(child);
        }
    }
    return parentElement;
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接