Using JavaScript to Create an XML table correctly

Viewed 70

I'm using an HTML file with JavaScript to parse an XML document and put all its data into a table. The XML file looks like this:

<?xml version="1.0"?> 
<orders> 
<order> 
    <customerid>2384</customerid> 
    <status>pending</status> 
    <item instock="Y" itemid="SD93"> 
        <name>Flying By Roller Skates</name> 
        <price>25.00</price> 
        <qty>25</qty> 
    </item> 
    <item instock="N" itemid="B12"> 
        <name>Bounce-o Ball</name> 
        <price>.35</price> 
        <qty>150</qty> 
    </item> 
</order> 
<order> 
    <customerid>5268</customerid> 
    <status>complete</status> 
    <item instock="Y" itemid="Q52"> 
        <name>Crash N Burn Skis</name> 
        <price>20</price> 
        <qty>10</qty> 
    </item> 
</order> 
<order> 
    <customerid>3384</customerid> 
    <status>pending</status> 
    <item instock="Y" itemid="PS93"> 
        <name>All Star Shoe</name> 
        <price>55.00</price> 
        <qty>12</qty> 
    </item> 
    <item instock="Y" itemid="M12"> 
        <name>All Star Hat</name> 
        <price>44.35</price> 
        <qty>15</qty> 
    </item> 
</order> 
<order> 
    <customerid>9008</customerid> 
    <status>pending</status> 
    <item instock="N" itemid="F32"> 
        <name>Fancy Shirt</name> 
        <price>120</price> 
        <qty>100</qty> 
    </item> 
</order> 
</orders> 

This is the JavaScript code in my HTML file:

        var output = "";
        var CustomerID = xmlDoc.getElementsByTagName("customerid");
        var Status = xmlDoc.getElementsByTagName("status");
        var Item = xmlDoc.getElementsByTagName("item");
        var Order = xmlDoc.getElementsByTagName("order");
        
        output += "<table border='1'>";
        output += "<tr>" + 
                    "<th>Customer ID</th>" +
                    "<th>Status</th>" +
                    "<th>Item Name</th>" +
                    "<th>Price</th>" +
                    "<th>Quantity</th>" +
                "</tr>";

        for(i=0; i<CustomerID.length; i++) {

          if(Status[i].innerHTML == "pending") {

              output += "<tr>";
              output += "<td rowspan='2'>" + CustomerID[i].innerHTML + "</td>";
              output += "<td rowspan='2'>" + Status[i].innerHTML + "</td>";

              for(i2=0; i2<Order[i].children.length; i2++) {

                if (Order[i].children[i2].nodeName == "item") {

                  for(i3=0; i3<Item[i2].children.length; i3++) {
                      output += "<td>" + Item[i2].children[i3].innerHTML + "</td>";
                  } 
                  output += "</tr>";
                  output += "<tr>";
                  
                  } else {
                    output += "";
                  }
              }
          } else {
            output += "";
          }
        }             
              output += "</table>";
              document.getElementById("table").innerHTML = output;

But I keep getting this table: My Table

it only selects those two items and I am unsure why. How can I change my code so that the table can be displayed properly?

1 Answers

Instead of grabbing all elements in the beginning, I'd suggest just selecting the orders, and looping through their children by selecting them inside the loop:

var orders = xmlDoc.getElementsByTagName('order');

for(i=0; i<orders.length; i++) {
  var order = orders[i];
  var customerid = order.children[0];
  var status = order.children[1];
  var item = order.children[2];

  var name = item.children[0];
  var price = item.children[1];
  var qty = item.children[2];
}

If you don't know if the children will be in that order, use getElementsByTagName:

for(i=0; i<orders.length; i++) {
  var order = orders[i];
  var customerid = order.getElementsByTagName('customerid')[0];
  var status = order.getElementsByTagName('status')[0];
  var item = order.getElementsByTagName('item')[0];

  var name = item.getElementsByTagName('name')[0];
  var price = item.getElementsByTagName('price')[0];
  var qty = item.getElementsByTagName('qty')[0];
}

Note: use lower cased variable names, since title case is used for classes

Related