Is it possible to load all nodes on button click using the XMLHttpRequest Object?

Why is it that when I insert the parent node, nothing shows up -- but when I use the root node ("dataroot"), only the first child node displays in the table even though there are multiple child/sibling nodes? Here's the HTML code:

<!DOCTYPE html>
<html>
<head>
    <title>
        Pharma-Find
    </title>
    <link rel="stylesheet" type="text/css" href="getDrugs.css">
    <script type = "text/javascript" src="getDrugs.js"></script>
</head>

<body>
    <button type="button" onclick="loadXMLDoc()">Pharma Find</button>
    <br><br>
    <table id="demo"></table>
</body>
</html>

This is the JS script:

function loadXMLDoc() {
  var xmlhttp = new XMLHttpRequest();
  xmlhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      myFunction(this);
    }
  };
  xmlhttp.open("GET", "drugA.xml", true);
  xmlhttp.send();
}
function myFunction(xml) {
  var i;
  var xmlDoc = xml.responseXML;
  var table="<tr><th>Generic Brand</th><th>Brand Name</th><th>lnk</th><th>purpose</th><th>DEASch</th><th>Category</th><th>Study Topic</th></tr>";
  var x = xmlDoc.getElementsByTagName("dataroot");
  for (i = 0; i <x.length; i++) { 
    table +=
    "<tr><td>" +
    x[i].getElementsByTagName("GenericName")[0].childNodes[0].nodeValue + 
    "</td><td>" +
    x[i].getElementsByTagName("BrandName")[0].childNodes[0].nodeValue +
    "</td><td>"+
    x[i].getElementsByTagName("lnk")[0].childNodes[0].nodeValue +
    "</td><td>" +
    x[i].getElementsByTagName("Purpose")[0].childNodes[0].nodeValue +
    "</td><td>" +
    x[i].getElementsByTagName("DEASch")[0].childNodes[0].nodeValue +
    "</td><td>" +
    x[i].getElementsByTagName("Category")[0].childNodes[0].nodeValue +
    "</td><td>" +
    x[i].getElementsByTagName("StudyTopic")[0].childNodes[0].nodeValue + "</td></tr>";
  }
  document.getElementById("demo").innerHTML = table;
}

Answer №1

To extract data from an XML document, utilize Query Selector and Xpath Expressions. Use the textContent property to retrieve text within an element or node.

I have included a sample Product item element node in the examples for creating a valid XML structure. By simplifying the child elements, you can observe how these methods function with just two elements.

Query selector employs CSS selectors to select and return elements.

const data = getXMLDocument();
const dataNodes = data.querySelectorAll('Product');

// fetch the table body
const tbody = document.querySelector('#OutputTarget tbody');
// remove all current child nodes
let node;
while (node = tbody.firstChild) {
  node.remove();
}

dataNodes.forEach(
  (product) => {
    // create and append a new tr
    const tr = tbody.appendChild(
      document.createElement('tr')
    );
    tr
      .appendChild(document.createElement('td'))
      .textContent = product.querySelector(':scope > GenericName')?.textContent
    tr
      .appendChild(document.createElement('td'))
      .textContent = product.querySelector(':scope > BrandName')?.textContent
  }
);

function getXMLDocument() {
  const xmlString = `<dataroot>
      <Product>
        <GenericName>One</GenericName>
        <BrandName>Awesome</BrandName>   
      </Product>
      <Product>
        <GenericName>Two</GenericName>
        <BrandName>Faboulous</BrandName>   
      </Product>
    </dataroot>`;
  return (new DOMParser()).parseFromString(xmlString, 'application/xml');
}
<table id="OutputTarget">
  <thead>
    <tr><th>Generic Brand</th><th>Brand Name</th></tr>
  </thead>
  <tbody>

  </tbody>
</table>

Xpath expressions offer a more detailed approach, supporting namespaces and enabling specific conditions while returning values directly.

const data = getXMLDocument();
const dataNodes = data.evaluate(
    '//Product', 
    data, 
    null, 
    XPathResult.ANY_TYPE, 
    null
);

// fetch the table body
const tbody = document.querySelector('#OutputTarget tbody');
// remove all current child nodes
let node;
while (node = tbody.firstChild) {
  node.remove();
}

// iterate the returned list
let productNode = dataNodes.iterateNext();
while (productNode) {
  // create and append a new tr
  const tr = tbody.appendChild(
    document.createElement('tr')
  );
  tr
    .appendChild(document.createElement('td'))
    .textContent = data.evaluate(
      'string(GenericName)', productNode, null, XPathResult.STRING_TYPE, null
    ).stringValue;
  tr
    .appendChild(document.createElement('td'))
    .textContent = data.evaluate(
      'string(BrandName)', productNode, null, XPathResult.STRING_TYPE, null
    ).stringValue;
  
  productNode = dataNodes.iterateNext();
}

function getXMLDocument() {
  const xmlString = `<dataroot>
      <Product>
        <GenericName>One</GenericName>
        <BrandName>Awesome</BrandName>   
      </Product>
      <Product>
        <GenericName>Two</GenericName>
        <BrandName>Faboulous</BrandName>   
      </Product>
    </dataroot>`;
  return (new DOMParser()).parseFromString(xmlString, 'application/xml');
}
<table id="OutputTarget">
  <thead>
    <tr><th>Generic Brand</th><th>Brand Name</th></tr>
  </thead>
  <tbody>
  
  </tbody>
</table>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue with error handling not being triggered when calling SAPUI5 function()

IBAN validation within a SAPUI5 Wizard is causing some issues for me. I am utilizing a functionImport on a V2 ODataModel (sap.ui.model.odata.v2.ODataModel) to perform this validation. Despite receiving a 202 status code, the request actually failed. Here ...

KafkaJS: tips for setting up a consumer on a website/server located remotely

I am currently working on setting up a live data streaming feature using Kafka for our company's website. My goal is to have a real-time updating plot displayed on the site. With the help of the kafkaJS documentation, I was able to create a functiona ...

Placing the jQuery/javascript source pages right before the closing body tag

Multiple plugin instructions recommend placing the javascript/jQuery source right before the closing body tag. I wondered why this advice is given, but couldn't find a clear explanation for it. In my experience, placing the src file anywhere in the s ...

Unable to display material-ui icon when using a conditional ternary statement in React

I'm facing an issue where my app crashes when attempting to display a mui icon based on a certain condition. I suspect the problem lies in how I am using PriceCheckIcon within {}. Can someone provide assistance? <span style={ ...

Ways to stop your browser from opening a new window when it is unable to recognize the address

When using a custom protocol to open a Windows application from my web application, everything works correctly without any issues. However, if the Windows application is not installed on the PC, a new window opens displaying "The address wasn't unders ...

Is there a way to execute a condition in a Vue component before rendering the HTML in the template?

Here is an example of my Vue component: <template> <div id="modal-transaction" class="modal fade" tabindex="-1" role="dialog"> ... <div class="modal-header"> <h4 class="modal ...

Is there a way to automatically recalculate the "Total Price" when the input values are adjusted?

Whenever I add an item to the cart, it gets appended to the row in the shopping cart, and the price adjusts accordingly. However, I'm having trouble getting the price to adjust whenever I change the input values (input type: "number"). I can't se ...

The side menu in Bootstrap dropdown experiences a one-time functionality

When navigating through a responsive top menu with Bootstrap, everything works seamlessly - from toggling the menu to dropdown functionality. However, I encountered an issue with the side menu as nav-pills used to select tab-panes. <div class="containe ...

Mystery of the Unresponsive MD Ripple Button

While working on creating a CSS button, I wanted to incorporate the Material Design ripple or wave effect into it. I came across a simple script on codepen that works well by adding the class "ripple" to various elements such as divs, buttons, images, and ...

Having trouble with the jQuery load function not functioning properly

I have encountered an issue with this code snippet while running it on XAMPP. The alert function is working fine, but the HTML content fails to load. I have included links to jQuery 3.2.1 for reference. index.html $(document).ready(function(){ $("#b ...

"The ng-route feature is not working as expected; instead of displaying the template url, it is showing

I'm currently developing a voting application as part of my freecodecamp project using the MEAN stack. I have completed the backend portion, but without user authentication for now. My focus now is on the frontend. I have created an HTML page that li ...

When using ng-repeat, it fails to showcase distinct JSON values and instead shows all the content from the JSON file in a single list item

My ng-repeat is not functioning as expected; instead of listing different JSON values, it's displaying the entire content of the JSON file in a single list item. Check out my CodePen example Here's my HTML: <div ng-app="myApp"> ...

Issue encountered during Firebase deployment: Module '@babel/runtime/helpers/builtin/interopRequireDefault' not found

Struggling to deploy firebase functions and encountering multiple issues. During the deployment process, facing a babel error: Error: Cannot find module '@babel/runtime/helpers/builtin/interopRequireDefault' at Function.Module._resolveFilen ...

Passing event handlers to Client Components within NextJS 13 and using the <button onClick={}> element is not supported

Oops! It looks like you can't pass event handlers to Client Component props. If you want your component to be interactive, consider converting some of it to a Client Component. const reqHelp = () => { Swal.fire({ title: '1', ...

Issues with Array.push causing improper pushes

UPDATE: I have now included the res.send(json) that was missing from the snippet. I'm currently working on a project that involves extracting/scraping data from a website and consolidating it into JSON format. However, when I call the endpoint, the r ...

What steps should I take to convert this from a string to HTML format?

I recently encountered an issue where my code was being converted into a string instead of the HTML output I intended to achieve. My main query is how can I convert this into innerHTML before it gets converted? Is there any way to accomplish this task if ...

The dynamic combination of jCarousel, jQuery Accordion, and fade in effects

Take a look at this link www.aboud-creative.com/demos/mckinley3. You'll find a jQuery Accordion with jCarousel inside the "Developments" section. I have implemented a standard fadeIn function for the logo, accordion, and a stag on the bottom right to ...

"Error: Multer is Unable to Read the Undefined File

Despite my best efforts, I am unable to get multer's file upload feature to work. Despite studying numerous tutorials and guides on YouTube, as well as diving into countless StackOverflow threads, I still struggle to make it function properly through ...

Simple organization of a table by sorting one column in a descending direction, all without the need for any additional plugins

Currently, I am working with a simple table containing several columns. My task involves sorting the table based on the values in the first column, which are integers. The sorting should only occur once and in descending order. I need to accomplish this ...

Refresh the form fields using ajax technology

Incorporating primefaces 5.0 into my project, I am attempting to create a set of input fields for each "user - product" combination where the total sum of values in the InputText fields within each panel can only amount to 100%. For instance, if there are ...