Reputation: 205
Here I have an example I'm building (with help).
Currently, the XML
is stored in a data island. But what if I wanted to make a request to an external server? Would I use an XMLHttpRequest
?
How would I code that in this example, and avoid the Cross Origin XMLHttpRequest problem?
In this example, I've tried playing with function loadXMLDoc(statelabel)
but without success.
Am I on the right track with this function?
function loadXMLDoc( statelabel ) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myFunction(this);
}
};
xhttp.open("GET", "state_data.xml", true);
xhttp.send();
}
Fully functional code here:
<!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>
Upvotes: 0
Views: 416
Reputation: 18950
This gets a little bit involved using vanilla XMLHttpRequest to load XML. Here is a quick sample.
function loadXMLDoc() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myFunction(this);
}
};
xmlhttp.open("GET", "sample.xml" , true);
xmlhttp.send();
}
function myFunction(xml) {
var x, i, xmlDoc, table;
xmlDoc = xml.responseXML;
table = "<tr><th>Artist</th><th>Title</th></tr>";
x = xmlDoc.getElementsByTagName("CD")
for (i = 0; i < x.length; i++) {
table += "<tr><td>" +
x[i].getElementsByTagName("ARTIST")[0].childNodes[0].nodeValue +
"</td><td>" +
x[i].getElementsByTagName("TITLE")[0].childNodes[0].nodeValue +
"</td></tr>";
}
document.getElementById("demo").innerHTML = table;
}
However, it gets much more complicated esp. if you want to do a cross-domain request.
That's probably the right moment to pick up jQuery to make things easier:
$.ajax({
url: 'https://www.w3schools.com/xml/note.xml',
dataType: 'XML',
type: 'GET',
async: false,
crossDomain: true,
success: function () { },$.ajax({
url: 'https://www.w3schools.com/xml/note.xml',
dataType: 'XML',
type: 'GET',
async: false,
crossDomain: true,
success: function () { },
failure: function () { },
complete: function (xml) {
// Parse the xml file and get data
var xmlDoc = $.parseXML(xml);
$xml = $(xmlDoc);
$xml.find('body').each(function () {
console.log($(this).text());
});
}
});
Upvotes: 1