Home > Software engineering >  How to loop xml document using javascript
How to loop xml document using javascript

Time:05-20

HTML CODE FOR THE PROBLEM Anyone please help out in traversing through each node of the XML document !

<!DOCTYPE html>
    <html>
    <head>
    <meta charset="ISO-8859-1">
    <title>Insert title here</title>
    </head>
    <body>
    <h1>AJAX JSON example</h1>
    
    <script>
    function loadDoc(){
    console.log('loadDoc');
    var xhttp= new XMLHttpRequest();
    
    
    
    xhttp.onreadystatechange=function()
    {
    if (this.readyState == 4 && this.status == 200){
    xhttp=xhttp.responseXML;
    
    document.getElementById("name").innerHTML= xhttp.getElementsByTagName("name")[0].childNodes[0].nodeValue;
    document.getElementById("company").innerHTML= xhttp.getElementsByTagName("company")[0].childNodes[0].nodeValue;
    document.getElementById("phone").innerHTML= xhttp.getElementsByTagName("phone")[0].childNodes[0].nodeValue;
    }
    };
    xhttp.open("GET","address.xml",true);
    xhttp.send();
    }
    
    </script>
    
    <div>
    <b>Name:</b>  <span id="name"></span><br>
    <b>Company:</b> <span id="company"></span><br>
    <b>Phone:</b> <span id="phone"></span><br>
    <button type="button" onclick="loadDoc()">
    change button</button>
    <button type="button" onclick="loadDoc()">
    Next</button>
    <button type="button" onclick="loadDoc()">
    Previous</button>
    </div>
    
    </body>
    </html>

XML CODE FOR THE PROBLEM

 <?xml version="1.0"?>
    <staff>
    <contact-info>
        <name>Rinku</name>
        <company>Bihar University</company>
        <phone>91987897876</phone>
    </contact-info> 
    <contact-info>
        <name>Rinki</name>
        <company>University</company>
        <phone>9145397876</phone>
    </contact-info> 
    <contact-info>
        <name>Rinka</name>
        <company>Bir University</company>
        <phone>9198347876</phone>
    </contact-info> 
    </staff>

HOW TO LOOP THROUGH EACH XML NODE USING NEXT AND PREVIOUS BUTTON. PLEASE HELP !!! I am able to fetch single node using the above code but can't loop through each of the node present in the above code !

CodePudding user response:

You are using 'getElementsByTagName("name")[0].childNodes[0]', only accessing element at first position 'index: 0', if in your XML comes more than 1 , you will always be accessing first, you need to make it dynamically, based on length of your content.

Here is another workaround:

var xmlStr = `<?xml version="1.0"?>
    <staff>
    <contact-info>
        <name>Rinku</name>
        <company>Bihar University</company>
        <phone>91987897876</phone>
    </contact-info> 
    <contact-info>
        <name>Rinki</name>
        <company>University</company>
        <phone>9145397876</phone>
    </contact-info> 
    <contact-info>
        <name>Rinka</name>
        <company>Bir University</company>
        <phone>9198347876</phone>
    </contact-info> 
    </staff>`;

function parseXml(xmlStr) {
    return new window.DOMParser().parseFromString(xmlStr, "text/xml");
}
let staffArr = [];
let xml = parseXml(xmlStr);
const nodesStaff = xml.getElementsByTagName('contact-info');
for (let node = 0; node < nodesStaff.length; node  ) {
    staffArr.push(nodesStaff[node].textContent.split('\n'));
}
//staffArr = staffArr.map(x=> x.filter(n=>n.trim()).map(r=>r.trim()));
staffArr.forEach((currentValue, index, arr) => {
    currentValue = currentValue.map(val => val.replace(/\s/g, ''));
    arr[index] = currentValue.filter(x => x);
});
console.info(staffArr);

CodePudding user response:

You're working with lists of nodes, but always address the first element (index zero). Using ID attributes is a problem in itself - they have to be unique for a whole document. Last you should iterate the outer contact-info nodes and fetch the values for each of them. Otherwise missing child nodes can lead to inconsistent values.

Some tricks to make you live easier:

  • You can use query selector (css selectors) to address nodes in any DOM document
  • data-attributes are a nice way to store configuration
  • Node.textContent reads/writes the whole content as plain text

Example:

// get the output container
const output = document.querySelector('#output');
// fetch the template inside it
const template = output.querySelector('.template');
// detach the template from the container
template.parentNode.removeChild(template);

// bootstrap xml document
const xmlDocument = (new DOMParser()).parseFromString(getXMLString(), "text/xml");

// use query selector on XML document
xmlDocument.querySelectorAll('contact-info').forEach(
  (contact) => {
    // clone template
    const section = template.cloneNode(true);
    // fetch placeholder nodes by data attribute
    const placeholders = section.querySelectorAll('[data-selector]');
    // fill placholder
    placeholders.forEach(
      (placeholder) => placeholder.textContent = contact.querySelector(
        placeholder.dataset.selector
      )?.textContent || ''
    );
    // append new section
    output.appendChild(section);
  }
);

function getXMLString() {
  return `<?xml version="1.0"?>
    <staff>
    <contact-info>
        <name>Rinku</name>
        <company>Bihar University</company>
        <phone>91987897876</phone>
    </contact-info> 
    <contact-info>
        <name>Rinki</name>
        <company>University</company>
        <phone>9145397876</phone>
    </contact-info> 
    <contact-info>
        <name>Rinka</name>
        <company>Bir University</company>
        <phone>9198347876</phone>
    </contact-info> 
    </staff>`;
}
<div id="output">
  <div >
    <b>Name:</b> <span data-selector="name"></span><br>
    <b>Company:</b> <span data-selector="company"></span><br>
    <b>Phone:</b> <span data-selector="phone"></span><br>
  </div>
</div>

  • Related