[英]How to find the node position of a value in an XML tree?
基於我在頁面上輸入的值,我想檢索相關的XML數據。
例如,如果我從頁面上的datalist
輸入字段中輸入/選擇option
“密歇根州”,我想在XML
文檔中查找密歇根州的node
位置。 通過了解node
位置,我可以從與密歇根州對應的XML
文檔中檢索其他信息,例如GDP
和POPULATION
。
我知道我應該將[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.