2

I also need to put the array in a variable.

I'm using .DataTable for pagination but it doesn't accept tables that are created from xml using Javascript and according to this https://datatables.net/forums/discussion/2689, I need to convert my xml into 2d array.

Here's my xml file

<person>
    <data>
        <name>juan</name>
        <city>tokyo</city>
        <age>20</age>
        <sex>m</sex>
    </data>
    <data>
        <name>pedro</name>
        <city>manila</city>
        <age>22</age>
        <sex>m</sex>
    </data>
    <data>
        <name>maria</name>
        <city>bangkok</city>
        <age>23</age>
        <sex>f</sex>
    </data>
</person>

My 2D array should look like this:

var person =[
    ["juan","tokyo","20","m"],
    ["pedro","manila","22","m"],
    ["maria","bangkok","23","f"],
];

This is my javascript code. The output shows on my html page but I cannot use it for the DataTable that is why i need to store it in an javascript array. How can I modify this code so i can put it in a variable instead of displaying it in an html page?

function readperson(){
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function(){
        if (this.readyState == 4 && this.status ==200){
            writeperson(this);
        }
    }
    xmlhttp.open("GET", "person.xml", true);
    xmlhttp.send();
}

function writeperson(xml){
    var x,i,xmlDoc,txt,ths,trs,tre,the;
    xmlDoc = xml.responseXML;
    var person =xmlDoc.getElementsByTagName("data");
    var l = person.length;
    var nodes = person[0].childNodes[0];
    //var l3 = nodes[0].length;
    var l2 = person[0].childNodes[0].nodeValue;

    var arr = [];
    //orders.length = 3 since two <data> tag
     for(i=0; i < person.length; i++){
        //will add brackets inside the array arr
        arr.push([]);//example: if arr.push("hello") output is hello,hello,hello
        
        arr[i][0]=person[i].getElementsByTagName("name")[0].childNodes[0].nodeValue
        arr[i][1]=person[i].getElementsByTagName("city")[0].childNodes[0].nodeValue
        arr[i][2]=person[i].getElementsByTagName("age")[0].childNodes[0].nodeValue
        arr[i][3]=person[i].getElementsByTagName("sex")[0].childNodes[0].nodeValue
    }
    document.getElementById("person").innerHTML = arr;
}

When I use a return statement instead of the innerHTML it does not work.

UPDATE I figured it out. Here's my final code

$(document).ready(function () {
  $.ajax({
    type: "GET",
    url: "person.xml",
    dataType: "xml",
    success: function (xml) {
      const res = [];
      $(xml).find("person > data").each(function (i, person) {
          res.push([
            $(this).find("name", person).text(),
            $(this).find("city", person).text(),
            $(this).find("age", person).text(),
            $(this).find("sex", person).text(),
          ]);
        });

      $("#person_table").DataTable({
        data: res,
        columns: [
          { title: "Name" },
          { title: "Address" },
          { title: "Age" },
          { title: "Sex." },
        ],
      });
    },
  });
});
0

3 Answers 3

1

Here is another Vanilla JS take on it with fetch() and DOMParser():

/* uncomment the next line for real application: */
// fetch("person.xml").then(r=>r.text()).then(txt=>{
  const atts="name,city,age,sex".split(",");
/* XML data string for SO demo, remove line for real application: */
  const txt = `<person><data><name>juan</name><city>tokyo</city><age>20</age><sex>m</sex></data><data><name>pedro</name><city>manila</city><age>22</age><sex>m</sex></data><data><name>maria</name><city>bangkok</city><age>23</age><sex>f</sex></data></person>`; 

  const xml=new DOMParser().parseFromString(txt,"text/html"),
    result=[...xml.querySelectorAll("data")].reduce((res,da)=>
      (res.push(atts.map(at=>da.querySelector(at).textContent)),res),
    []);
// Test
  console.log(result);

/* end of fetch(), uncomment next line for real application: */
// });

Sign up to request clarification or add additional context in comments.

2 Comments

how can I assign the result variable outside the fetch() function? I tried using return result and then declared var dataSet = fetch(). i then used dataSet as data source on my DataTable but it did not work.
This is a typical question with regards to asynchronous processing, see for answers here: stackoverflow.com/a/38869587/2610061
0

You can use jQuery (you have this tag below your question) to parse html tags. First convert XML data string to DOM HTML, then do all searching and extraction how you regularly would with jQuery:

// XML data string
const xml = `
<person>
    <data>
        <name>juan</name>
        <city>tokyo</city>
        <age>20</age>
        <sex>m</sex>
    </data>
    <data>
        <name>pedro</name>
        <city>manila</city>
        <age>22</age>
        <sex>m</sex>
    </data>
    <data>
        <name>maria</name>
        <city>bangkok</city>
        <age>23</age>
        <sex>f</sex>
    </data>
</person>
`;

// Convert to DOM HTML
const html = $.parseHTML(xml);

// Set array for result
const res = [];

// Parse html, find data tags,
// loop through it's content
$(html).find("data").each(function() {
  // For each data element push
  // required data to array
  res.push([
    $(this).find("name").text(),
    $(this).find("city").text(),
    $(this).find("age").text(),
    $(this).find("sex").text()
  ]);
});

// Test
console.log(res);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

3 Comments

how should I use the $.parseHTML(xml) when my xml is from a separate xml file?
You passing data to your writeperson function as xml variable, use it. You can try to put all this code inside writeperson function. Maybe you need to ectract xmlDoc = xml.responseXML; before and use xmlDoc instead, do some tests.
Or use $.ajax to read your xml file, like this: stackoverflow.com/a/19220964/10917379
0

Consider the following.

Example: https://jsfiddle.net/Twisty/1vw3z6mf/

JavaScript

$(function() {
  function xmlToArray(xml) {
    var arr = [];
    $(xml).find("person > data").each(function(i, person) {
      arr.push([
        $("name", person).text(),
        $("city", person).text(),
        $("age", person).text(),
        $("sex", person).text()
      ]);
    });
    console.log("Converted", arr);
    return arr;
  }

  function writeperson(xml) {
    console.log("Write People");
    var people = xmlToArray(xml);
    $("#person").html(people);
  }

  function readperson() {
    console.log("Read People");
    $.get("person.xml", function(data) {
      writeperson(data);
    });
  }

  $("button").click(readperson);
});

jQuery can read XML just like it can reach HTML. So you can use jQuery selectors to traverse the XML. You can do this with .find() or with $("elem", object) shorthand which is the same.

The logic iterates over each data portion and creates Arrays at each index. This gives you an Array of Arrays or a 2D Array that Datatables can use.

I cleaned up other code elements to all use jQuery, yet there is nothing wrong with using JavaScript if you choose.

2 Comments

I declared var dataSet = xmlToArray(xml); and then used the dataSet variable on my data table as data source but it seems like datatable does not recognize it. It shows an array on my page but the datatable is not applied
@randomnamesksksk how are you passing the Array to the Datatables? Please provide a Minimal, Reproducible Example: stackoverflow.com/help/minimal-reproducible-example

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.