Vanilla Javascript和XML - for循环问题

时间:2018-05-08 14:09:52

标签: javascript html xml

我遇到了一个我无法理解的奇怪错误。我认为这是堆叠for循环的问题,但我不完全确定。以下是我所做的简短说明:

我正在阅读带有Vanilla Javascript的XML文件,并以HTML(当前)显示信息,以查看我的代码是否有效。

每个条目都以HTML格式显示在表格行中。 “名称”得到它自己的“TD”,“关键词”也是如此。现在我想在“OL”中将每个“Step”显示为“LI”。

它应为每个元素“description”创建一个OL,但它为每个元素“description”创建OL,并将两个OL推送到一个TD。

结果是:两个有两个OL的TD。

我是否错误地堆叠了for循环还是我犯了另一个错误?

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>

预期产出:

<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>

我的输出:

<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>

更新(09.05.2018):

我喜欢下面发布的方法,我正努力让它发挥作用。它还没有正常工作,但我会先发布Javascript:

我有一个函数“loadXML()”就是这样做的(“sO(this);”调用函数来创建表等。):

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();
}

我更改了main函数的变量以包含我的外部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;
...

预期结果与您在评论中可以看到的表类似。 但我的输出是:[object XMLDocument]。 “CreateContextualFragment()” - 方法不能正确读取XML文件,但我不确定这是否真的是错误。 Screenshot

最后更新: 我发现了这个错误。我不得不添加

xmlhttp.dataType = "text";  

到我的loadXML()并更改

var xml = xml.responseXML;  

var xml = xml.response;  

现在它运作得很好。谢谢你的帮助!

1 个答案:

答案 0 :(得分:0)

我认为你的问题源于document.getElementsByTagName。您应该将搜索本地化为任何给定的entry

,而不是引用文档

以下是我对你的问题的看法:

//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);
});