我遇到了一个我无法理解的奇怪错误。我认为这是堆叠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;
现在它运作得很好。谢谢你的帮助!
答案 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);
});