简体   繁体   中英

Vanilla Javascript and XML - For-loop issue

I am encountering a weird error I can't quite grasp. I think it is an issue with stacked for-loops, but I am not exactly sure. Here is a short explanation of what I do:

I am reading an XML-File with Vanilla Javascript and display the information in HTML (currently) to see if my code works.

Each entry gets displayed in a table-row in HTML. "Name" gets it's own "TD" and so does "Keywords". Now I want to display every "Step" as "LI" in an "OL".

It should create one OL for every element "description", but it creates OLs for EVERY element "description" and pushes both OLs into one TD.

The result is: 2 TDs with both OLs.

Did I stack the for-loops incorrectly or did I make another mistake?

 var getDESC = document.getElementsByTagName("description"); var tblROW = document.createElement("TR"); var tblDATA = document.createElement("TD"); var tbl = document.getElementById("tbl"); var k; for (k = 0; k < getDESC.length; k++) { var createOL = document.createElement('OL'); var l; for (l = 0; l < getDESC[k].getElementsByTagName("step").length; l++) { var createLI = document.createElement("LI"); var createStep = ''; createStep = document.createTextNode(getDESC[k].getElementsByTagName("step")[l].childNodes[0].nodeValue); createLI.appendChild(createStep); createOL.appendChild(createLI); } tblDATA.appendChild(createOL); tblROW.appendChild(tblDATA); } tbl.appendChild(tblROW); 
 <content> <entry> <name></name> <keywords></keywords> <description> <step>Text 1</step> <step>Text 2</step> <step>Text 3</step> </description> </entry> <entry> <name></name> <keywords></keywords> <description> <step>Text 1</step> <step>Text 2</step> <step>Text 3</step> </description> </entry> </content> <table> <tbody id="tbl"></tbody></table> 

Expected Output:

<table>
 <tr>
  <td>Name</td>
  <td>Keywords</td>
  <td>
   <ol>"Orderered list for entry #1"</ol>
  </td>
 </tr>
 <tr>
  <td>Name</td>
  <td>Keywords</td>
  <td>
   <ol>"Orderered list for entry #2"</ol>
  </td>
 </tr>
</table>

My Output:

<table>
 <tr>
  <td>Name for entry #1</td>
  <td>Keywords for entry #1</td>
  <td>
   <ol>"Orderered list for entry #1"</ol>
   <ol>"Orderered list for entry #2"</ol>
  </td>
 </tr>
 <tr>
  <td>Name for entry #2"</td>
  <td>Keywords for entry #2"</td>
  <td>
   <ol>"Orderered list for entry #1"</ol>
   <ol>"Orderered list for entry #2"</ol>
  </td>
 </tr>
</table>

UPDATE (09.05.2018):

I like the approach posted below and I'm trying to make it work. It doesn't work correctly yet, but I will post the Javascript first:

I have a function "loadXML()" that does exactly that ("sO(this);" calls the function to create the table etc.):

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

I changed the variable of the main-function to include my external XML-File:

function sO(xml){
//following line should load the XML-File
var xml = xml.responseXML;
var xmlObject = document.createRange().createContextualFragment(xml);
document.body.appendChild(document.createElement("h1")).textContent = "XML";
document.body.appendChild(document.createElement("pre")).textContent = xml;
...

The expected result would be similar to the table you can see below in the comment. But my output is: [object XMLDocument]. The "CreateContextualFragment()"-method doesn't read the XML-File correctly I guess, but I am not sure if that really is the mistake. Screenshot

Final Update: I discovered the mistake. I had to add

xmlhttp.dataType = "text";  

to my loadXML() and change

var xml = xml.responseXML;  

to

var xml = xml.response;  

Now it works just fine. Thank your for your help!

I think your problems stems from document.getElementsByTagName . Instead of referencing the document you should be localize your search to any given entry .

Here is my take on your problem:

 //XML var xml = "<content>\\n<entry>\\n <name>Name1</name>\\n <keywords>key_1 key_3 key_4</keywords>\\n <description>\\n\\t<step>Text 1</step>\\n\\t<step>Text 2</step>\\n\\t<step>Text 3</step>\\n </description>\\n</entry>\\n<entry>\\n <name>Name2</name>\\n <keywords>key_2</keywords>\\n <description>\\n\\t<step>Text 1</step>\\n\\t<step>Text 2</step>\\n </description>\\n</entry>\\n</content>"; var xmlObject = document.createRange().createContextualFragment(xml); document.body.appendChild(document.createElement("h1")).textContent = "XML"; document.body.appendChild(document.createElement("pre")).textContent = xml; //Table document.body.appendChild(document.createElement("h1")).textContent = "HTML"; var table = document.body.appendChild(document.createElement("table")); table.innerHTML = "<tr><th>name</th><th>keywords</th><th>description</th></tr>"; table.border = "true"; //treat data xmlObject.querySelectorAll("entry") .forEach(function (entry) { var row = document.createElement("tr"); //name row .appendChild(document.createElement("td")) .textContent = entry.querySelector("name").textContent; //keywords row .appendChild(document.createElement("td")) .textContent = entry.querySelector("keywords").textContent; //description var descriptions = row .appendChild(document.createElement("td")) .appendChild(document.createElement("ol")); entry .querySelector("description") .querySelectorAll("step") .forEach(function (step) { descriptions .appendChild(document.createElement("li")) .textContent = step.textContent; }); table.appendChild(row); }); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM