繁体   English   中英

如何在XML树中查找值的节点位置?

[英]How to find the node position of a value in an XML tree?

基于我在页面上输入的值,我想检索相关的XML数据。

例如,如果我从页面上的datalist输入字段中输入/选择option “密歇根州”,我想在XML文档中查找密歇根州的node位置。 通过了解node位置,我可以从与密歇根州对应的XML文档中检索其他信息,例如GDPPOPULATION

我知道我应该将[1]更改为[i]类的变量,但是该如何编码该函数?

 var n = document.getElementById("myInputId"); n.addEventListener("keyup", function(event) { event.preventDefault(); if (event.keyCode === 13) { document.getElementById("myButton").click(); } }); function loadXMLDoc() { var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { myFunction(xmlhttp); } }; xmlhttp.open("GET", "state_data.xml", true); xmlhttp.send(); } function myFunction(xml) { var x, i, xmlDoc; xmlDoc = xml.responseXML; x = xmlDoc.getElementsByTagName("UNIT") var s = xmlDoc.getElementsByTagName("STATE")[1].childNodes[0].nodeValue; document.getElementById("state").innerHTML = s; var gElem = xmlDoc.getElementsByTagName("GDP"); var g = (gElem.length > 0) ? gElem[1].childNodes[0].nodeValue : ""; document.getElementById("gdp").innerHTML = g; var pElem = xmlDoc.getElementsByTagName("POPULATION"); var p = (pElem.length > 0) ? pElem[1].childNodes[0].nodeValue : ""; document.getElementById("population").innerHTML = p; var a = n.value document.getElementById("inputValue").innerHTML = a; xmlDoc.UNITs.forEach(function(e, z) { var q = document.getElementById("inputValue").innerHTML; if (e.properties.id == q) { document.getElementById("nodePosition").innerHTML = z; } }); } 
 <body onload="loadXMLDoc()"> <input list="myInput" id="myInputId" value=""> <button id="myButton" onClick="loadXMLDoc()">submit</button> <p>input value: <span id="inputValue"></span></p> <p>XML tree node position of input value: <span id="nodePosition"></span></p> <p>State: <span id="state"></span></p> <p>GDP: <span id="gdp"></span></p> <p>Population: <span id="population"></span></p> <datalist id="myInput"> <option id="AL">Alabama</option> <option id="CA">California</option> <option id="MI">Michigan</option> <option id="TX">Texas</option> <option id="WI">Wisconsin</option> </datalist> 

这是我的XML:

<?xml version="1.0" encoding="UTF-8"?>
<STATE_DATA>
 <UNIT>
    <STATE>Wisconsin</STATE>
    <GDP>232,300,000,000</GDP>
    <POPULATION>5,800,000</POPULATION>
 </UNIT>
 <UNIT>
    <STATE>Alabama</STATE>
    <GDP>165,800,000,000</GDP>
    <POPULATION>4,900,000</POPULATION>
 </UNIT>
 <UNIT>
    <STATE>California</STATE>   
    <!-- Note: the GDP node for this unit is missing -->
    <POPULATION>39,600,000</POPULATION>
 </UNIT>
 <UNIT>
    <STATE>Texas</STATE>
    <GDP>1,600,000,000,000</GDP>
    <POPULATION>28,300,000</POPULATION>
 </UNIT>
 <UNIT>
    <STATE>Michigan</STATE>
    <GDP>382,000,000</GDP>
    <POPULATION>10,000,000</POPULATION>
 </UNIT>
</STATE_DATA>

如果您诉诸于现代浏览器附带的xml处理功能,则事情会有所简化。 重写围绕XPath表达式进行。 完整的介绍超出了此答案的范围,但是简而言之,它是一种从xml树检索内容的模式语言。

xpath表达式用于从xml文件中提取相关元素。

该解决方案不需要对xml进行任何事先修改(与该解决方案的先前版本相反)。

该代码示例是独立的-只需将其保存为本地html文件或从http服务器提供即可。 为了使其工作,xml数据存储在脚本元素中,用作数据岛。

将设计更改回使用ajax调用来获取xml数据应该很简单。

考虑将代码作为概念证明,介绍基于xpath的方法的结构。

<!DOCTYPE html>
<!--
    SO
    datalist / xml handling
    Q 51200490 (https://stackoverflow.com/questions/51200490/how-to-find-the-node-position-of-a-value-in-an-xml-tree/51201494)
    A 
-->
<html>
    <head>
        <title>SO sample</title>
        <script>
 // Setup of keypress event handler, default selection of xml data.
 function setupEH () {
    var n = document.getElementById("myInputId");
    n.addEventListener("keyup", function(event) {
        event.preventDefault();
        if (event.keyCode === 13) {
            document.getElementById("myButton").click();
        }
    });

    loadXMLDoc('Alabama'); // comment out this line if you want a vanilla UI after loading the html page.
}

// Load the xml document
function loadXMLDoc( statelabel ) {
    // The xml document is retrieved with the following steps:
    //      1. Obtain the (in-document) source as a DOM node.
    //      2. Extract textual content.
    //      3. Instantiate the xml parser (a browser built-in)
    //      4. Parse textual content into an xml document
    //
    //  When retrieving the xml document by means of ajax, these steps will be handled by the library for you - a parsed xml document will be available as a property or through calling a method.
    //
    let x_xmlisland = document.getElementById("template_xml");
    let s_xmlsource = x_xmlisland.textContent; 
    let parser = new DOMParser();
    let xmlDoc = parser.parseFromString(s_xmlsource, "application/xml");

    myFunction(xmlDoc, statelabel); // Actual work ...
}

// Processing the xml document 
function myFunction(xmlDoc, statelabel) {
    //    debugger; // uncomment to trace

    //
    //  Every bit of information is processed as follows:
    //      - Get the relevant xml subtree ( `UNIT` element of the selected state incl.descendants )
    //      - Extract the textual value.
    //      - Feed the textual value to the Html elements prsenting the result.
    //
    var xpr_current_unit  = xmlDoc.evaluate("/STATE_DATA/UNIT[./STATE[./text() = '"+statelabel+"']]",xmlDoc,null,XPathResult.ORDERED_NODE_ITERATOR_TYPE,null);
    var node_current_unit = xpr_current_unit.iterateNext();

    //
    //  The subsequent calls to xmlDoc.evaluate set the current UNIT element as their context node ('starting point'/'temporary root' for the xpath expression).
    //  The context node is referenced by '.' (dot) 
    //
    var xpr_s   = xmlDoc.evaluate("./STATE/text()",node_current_unit,null,XPathResult.ORDERED_ANY_TYPE,null);
    var node_s  = xpr_s.iterateNext();
    var s       = node_s.textContent
    document.getElementById("state").innerHTML = s;

    var xpr_g   = xmlDoc.evaluate("./GDP/text()",node_current_unit,null,XPathResult.ORDERED_ANY_TYPE,null);
    var node_g  = xpr_g.iterateNext();
    var g = "Unknown";
    if ( node_g !== null ) {
        g = node_g.textContent;
    }
    document.getElementById("gdp").innerHTML = g;

    var xpr_p   = xmlDoc.evaluate("./POPULATION/text()",node_current_unit,null,XPathResult.ORDERED_ANY_TYPE,null);
    var node_p  = xpr_p.iterateNext();
    var p = "Unknown";
    if ( node_p !== null ) {
        p = node_p.textContent;
    }
    document.getElementById("population").innerHTML = p;

    // cf. https://stackoverflow.com/a/3437009
    var xpr_u  = xmlDoc.evaluate("count(./preceding::UNIT)+1.",node_current_unit,null,XPathResult.ORDERED_ANY_TYPE,null);
    var n_ucount = xpr_u.numberValue;

    document.getElementById("inputValue").innerHTML = s;
    document.getElementById("nodePosition").innerHTML = n_ucount;
}

// Setup the submit click handler
function ehClick ( ) {
    let node_choice     = document.getElementById('myInputId');
    loadXMLDoc(node_choice.value);
}
        </script>
        <style>
        </style>
    </head>
    <body onload="setupEH()">
        <script id="template_xml" type="text/xml"><?xml version="1.0" encoding="UTF-8"?>
<STATE_DATA>
 <UNIT>
    <STATE>Wisconsin</STATE>
    <GDP>232,300,000,000</GDP>
    <POPULATION>5,800,000</POPULATION>
 </UNIT>
 <UNIT>
    <STATE>Alabama</STATE>
    <GDP>165,800,000,000</GDP>
    <POPULATION>4,900,000</POPULATION>
 </UNIT>
 <UNIT>
    <STATE>California</STATE>   
    <!-- Note: the GDP node for this unit is missing -->
    <POPULATION>39,600,000</POPULATION>
 </UNIT>
 <UNIT>
    <STATE>Texas</STATE>
    <GDP>1,600,000,000,000</GDP>
    <POPULATION>28,300,000</POPULATION>
 </UNIT>
 <UNIT>
    <STATE>Michigan</STATE>
    <GDP>382,000,000</GDP>
    <POPULATION>10,000,000</POPULATION>
 </UNIT>
</STATE_DATA>
        </script>
        <input list="myInput" id="myInputId" value="">
        <button id="myButton" onClick="ehClick()">submit</button>

        <p>input value: <span id="inputValue"></span></p>
        <p>XML tree node position of input value: <span id="nodePosition"></span></p>
        <p>State: <span id="state"></span></p>
        <p>GDP: <span id="gdp"></span></p>
        <p>Population: <span id="population"></span></p>

        <datalist id="myInput">
        <option id="AL">Alabama</option>
        <option id="CA">California</option>
        <option id="MI">Michigan</option>
        <option id="TX">Texas</option>
        <option id="WI">Wisconsin</option>
        </datalist>
    </body>
</html>

参考

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM