You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XML parentNode属性无法识别,XPath结合JS解析遇问题

解析XML时获取父节点的问题解决

问题背景

本人是XML和JS新手,现尝试解析XML并收集所有<name>节点(后续需存入表格)。待解析的XML片段如下:

<?xml version="1.0" encoding="UTF-8"?>
<model-data>
    <identification>
        <date>Thu Dec 15 14:43:07 CET 2022</date>
        <xml-version>4.11</xml-version>
    </identification>
    <model>
        <named-domains>
            <named-domain>
                <name>boolean</name>
                <elements>
                    <element>
                        <value>0</value>
                        <name>No</name>
                        <description>No</description>
                    </element>
                    <element>
                        <value>1</value>
                        <name>Yes</name>
                        <description>Yes</description>
                    </element>
                </elements>
            </named-domain>
            <named-domain>
                <name>D_NOME_TECNICO_COMPLETO</name>
                <elements>
                    <element>
                        <value>0</value>
                        <name>PippoBaudo</name>
                        <description>Superstar</description>
                    </element>
                        ... // same pattern
                </elements>
            </named-domain>
        </named-domains>
    </model>
</model-data>

现有JS代码

<!DOCTYPE html>
<html>

<body>

    <p id="demo"></p>

    <script>
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function () {
            if (this.readyState == 4 && this.status == 200) {
                showResult(xhttp.responseXML);
            }
        };
        xhttp.open("GET", "prova.xml", true);
        xhttp.send();

        function showResult(xml) {
            var txt = "";
            // path = "//named-domain/name[text()]";
            path = "/model-data/model/named-domains//name[text()]";
            if (xml.evaluate) {
                var nodes = xml.evaluate(path, xml, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
                var result = nodes.iterateNext();
                while (result) {
                        txt += "<b>" + result.childNodes[0].nodeValue + "</b><br>";
                        result = nodes.iterateNext();
                        parente = nodes.parentnode.nodevalue; // <- Here something goes wrong!

                }
                // Code For Internet Explorer
            } else if (window.ActiveXObject || xhttp.responseType == "msxml-document") {
                xml.setProperty("SelectionLanguage", "XPath");
                nodes = xml.selectNodes(path);
                for (i = 0; i < nodes.length; i++) {
                    txt += nodes[i].childNodes[0].nodeValue + "<br>";
                }
            }
            document.getElementById("demo").innerHTML = txt;

        }
    </script>
</body>

</html>

遇到的问题

  • VS Code未提示nodes有parentnode属性;
  • 强制写入后出现报错:Uncaught TypeError: Cannot read properties of undefined (reading 'nodeValue')。

解决方案

错误原因分析

  1. nodes是XPathResult迭代器对象,不是DOM节点,因此它本身没有parentNode属性;
  2. 属性名写法错误:DOM节点的父节点属性是驼峰式的parentNode,不是小写的parentnode;nodeValue同样需要驼峰写法。

修正后的代码逻辑

要获取当前<name>节点的父节点,需要从迭代到的result(当前DOM节点)上获取,而不是从nodes迭代器获取。同时要注意调用iterateNext()的时机——应该先处理当前节点的父节点,再获取下一个节点。

以下是修正后的showResult函数核心部分:

function showResult(xml) {
    var txt = "";
    path = "/model-data/model/named-domains//name[text()]";
    if (xml.evaluate) {
        var nodes = xml.evaluate(path, xml, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
        var result = nodes.iterateNext();
        while (result) {
            var nameValue = result.childNodes[0].nodeValue;
            txt += "<b>" + nameValue + "</b><br>";
            
            // 获取当前name节点的直接父节点
            var parentNode = result.parentNode;
            txt += "直接父节点:" + parentNode.nodeName + "<br>";

            // 如果需要找到所属的<named-domain>节点(针对element下的name)
            if (parentNode.nodeName === "element") {
                var namedDomainNode = parentNode.parentNode.parentNode;
                var domainName = namedDomainNode.querySelector("name").textContent;
                txt += "所属域:" + domainName + "<br>";
            }

            // 迭代下一个节点
            result = nodes.iterateNext();
        }
    } else if (window.ActiveXObject || xhttp.responseType == "msxml-document") {
        xml.setProperty("SelectionLanguage", "XPath");
        nodes = xml.selectNodes(path);
        for (i = 0; i < nodes.length; i++) {
            var nameValue = nodes[i].childNodes[0].nodeValue;
            txt += nameValue + "<br>";
            var parentNode = nodes[i].parentNode;
            txt += "直接父节点:" + parentNode.nodeName + "<br>";
        }
    }
    document.getElementById("demo").innerHTML = txt;
}

额外建议

  • 如果只需要<named-domain>下的<name>节点,可以修改XPath表达式为/model-data/model/named-domains/named-domain/name,避免获取到<element>下的<name>;
  • 可以使用result.textContent替代result.childNodes[0].nodeValue,更简洁且兼容性更好。

内容的提问来源于stack exchange,提问作者PaNicorp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 20:50:26