【问题标题】:XML DOM Looping through element nodesXML DOM 循环遍历元素节点
【发布时间】:2020-08-26 20:40:43
【问题描述】:

我正在学习 W3 XML DOM 教程。我不明白为什么迭代会在输出中产生 1、3、5、7。我了解其他所有内容(我想!)有人可以帮忙解释一下吗?谢谢。

<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        myFunction(this);
    }
};
xhttp.open("GET", "books.xml", true);
xhttp.send();

function myFunction(xml) {
    var x, y, i, xlen, xmlDoc, txt;
    xmlDoc = xml.responseXML;
    x = xmlDoc.getElementsByTagName("book")[0];
    xlen = x.childNodes.length;
    y = x.firstChild;
    txt = "";
    for (i = 0; i < xlen; i++) {
        if (y.nodeType == 1) {
            txt += i + " " + y.nodeName + "<br>";
        }
        y = y.nextSibling;
    }
    document.getElementById("demo").innerHTML = txt; 
}
</script>

</body>
</html>

输出是:

1 title
3 author
5 year
7 price

你好 Andy,这是 xml DOM 文件,来自https://www.w3schools.com/xml/dom_nodes.asp

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
  <book category="cooking">
    <title lang="en">Everyday Italian</title>
    <author>Giada De Laurentiis</author>
    <year>2005</year>
    <price>30.00</price>
  </book>
  <book category="children">
    <title lang="en">Harry Potter</title>
    <author>J K. Rowling</author>
    <year>2005</year>
    <price>29.99</price>
  </book>
  <book category="web">
    <title lang="en">XQuery Kick Start</title>
    <author>James McGovern</author>
    <author>Per Bothner</author>
    <author>Kurt Cagle</author>
    <author>James Linn</author>
    <author>Vaidyanathan Nagarajan</author>
    <year>2003</year>
    <price>49.99</price>
  </book>
  <book category="web" cover="paperback">
    <title lang="en">Learning XML</title>
    <author>Erik T. Ray</author>
    <year>2003</year>
    <price>39.95</price>
  </book>
</bookstore>

针对 Carlos22 的回答的其他 cmets。对不起,卡洛斯,我还是不明白。

(y.nodeType ==1) 将始终返回 true,因为第一次出现 &lt;book&gt; 的子元素都是 type element (nodeType = 1)

第一个循环i = 0 所以txt 的值应该是0 title

第二个循环i = 1 所以0 title 应该与1 author 连接所以字符串txt 的值现在是0 title 1 author

第三个循环i = 2 txt 包含字符串0 title 1 author 2 year 等等。

我有时会变得非常愚蠢,所以请原谅!

【问题讨论】:

  • 你能在这个例子中包含你的 xml 吗?
  • 你好安迪,这是 xml DOM:

标签: javascript xml dom


【解决方案1】:

由于if (y.nodeType == 1),您的代码仅计算“元素节点”。

这是所有节点的示例:

const xml = `<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
  <book category="cooking">
    <title lang="en">Everyday Italian</title>
    <author>Giada De Laurentiis</author>
    <year>2005</year>
    <price>30.00</price>
  </book>
  <book category="children">
    <title lang="en">Harry Potter</title>
    <author>J K. Rowling</author>
    <year>2005</year>
    <price>29.99</price>
  </book>
  <book category="web">
    <title lang="en">XQuery Kick Start</title>
    <author>James McGovern</author>
    <author>Per Bothner</author>
    <author>Kurt Cagle</author>
    <author>James Linn</author>
    <author>Vaidyanathan Nagarajan</author>
    <year>2003</year>
    <price>49.99</price>
  </book>
  <book category="web" cover="paperback">
    <title lang="en">Learning XML</title>
    <author>Erik T. Ray</author>
    <year>2003</year>
    <price>39.95</price>
  </book>
</bookstore>`;

function getXmlFromText(xml) {
  parser = new DOMParser();
  return parser.parseFromString(xml, "text/xml");
}

function getNodeTypeStr(nodeType) {
  if (nodeType == 1) return 'ELEMENT_NODE';
  if (nodeType == 3) return 'TEXT_NODE';
  return 'Read the DOCS: https://www.w3schools.com/xml/dom_nodetype.asp';
}

function myFunction(xmlDoc) {
  var x, y, i, xlen, txt;
  //xmlDoc = xml.responseXML;
  x = xmlDoc.getElementsByTagName("book")[0];
  xlen = x.childNodes.length;
  y = x.firstChild;
  txt = ""; var txt2 = '';
  for (i = 0; i < xlen; i++) {
    if (y.nodeType == 1) {
      txt += i + " " + y.nodeName + "<br>";
    }
    txt2 += i + ' - ' + y.nodeName + ' - ' + getNodeTypeStr(y.nodeType) + ' - ' + y.nodeValue + '<br>';
    y = y.nextSibling;
  }
  document.getElementById("demo").innerHTML = txt;
  document.getElementById("allnodes").innerHTML = txt2;
}

myFunction(getXmlFromText(xml));
div {
 padding: 2px;
 border: 1px solid gray;
 margin-bottom: 4px;
}
Only element nodes:
<div id="demo"></div>
All nodes:
<div id="allnodes"></div>

打包的 XML 示例:

const xml = `<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
  <book category="cooking">
    <title lang="en">Everyday Italian</title><author>Giada De Laurentiis</author>
    <year>2005</year>
    <price>30.00</price>
  </book>
  <book category="children">
    <title lang="en">Harry Potter</title>
    <author>J K. Rowling</author>
    <year>2005</year>
    <price>29.99</price>
  </book>
  <book category="web">
    <title lang="en">XQuery Kick Start</title>
    <author>James McGovern</author>
    <author>Per Bothner</author>
    <author>Kurt Cagle</author>
    <author>James Linn</author>
    <author>Vaidyanathan Nagarajan</author>
    <year>2003</year>
    <price>49.99</price>
  </book>
  <book category="web" cover="paperback">
    <title lang="en">Learning XML</title>
    <author>Erik T. Ray</author>
    <year>2003</year>
    <price>39.95</price>
  </book>
</bookstore>`;

function getXmlFromText(xml) {
  parser = new DOMParser();
  return parser.parseFromString(xml, "text/xml");
}

function getNodeTypeStr(nodeType) {
  if (nodeType == 1) return 'ELEMENT_NODE';
  if (nodeType == 3) return 'TEXT_NODE';
  return 'Read the DOCS: https://www.w3schools.com/xml/dom_nodetype.asp';
}

function myFunction(xmlDoc) {
  var x, y, i, xlen, txt;
  //xmlDoc = xml.responseXML;
  x = xmlDoc.getElementsByTagName("book")[0];
  xlen = x.childNodes.length;
  y = x.firstChild;
  txt = ""; var txt2 = '';
  for (i = 0; i < xlen; i++) {
    if (y.nodeType == 1) {
      txt += i + " " + y.nodeName + "<br>";
    }
    txt2 += i + ' - ' + y.nodeName + ' - ' + getNodeTypeStr(y.nodeType) + ' - ' + y.nodeValue + '<br>';
    y = y.nextSibling;
  }
  document.getElementById("demo").innerHTML = txt;
  document.getElementById("allnodes").innerHTML = txt2;
}

myFunction(getXmlFromText(xml));
div {
 padding: 2px;
 border: 1px solid gray;
 margin-bottom: 4px;
}
Only element nodes:
<div id="demo"></div>
All nodes:
<div id="allnodes"></div>

【讨论】:

  • 那就解释了。什么我不明白为什么文本节点在元素节点前面?
  • @andymeissner 因为不在标签内的每个文本都被视为文本节点。在我们的例子中,它只是......空格和换行符。
  • 哦,就是这样。因为我试图用 jsfiddle 重现它但不能因为我删除了空格和换行符:D
  • @andymeissner 我已将打包的 XML 示例添加到我的答案中。看一看。我通过删除不必要的换行删除了 1 个文本节点 :)
  • 谢谢大家,我开始明白了。只需要进一步消化你的cmets。谢谢。
【解决方案2】:

这是因为验证y.nodeType == 1 是真的,它存储在txt += i + " " + y.nodeName + "&lt;br&gt;";;这意味着当y.nodeType == 1truei在下一个循环中为1,而i为2,y.nodeType == 1为假,然后在下一个循环中,当i为3时y.nodeType == 1true和所以。

【讨论】:

  • 你好卡洛斯,我还是不明白。查看我添加到帖子中的其他 cmets。
  • 谢谢大家。我有点开始明白了。是时候消化你的 cmets 了!谢谢。
【解决方案3】:

在 Anton 和 Andy Meissner 的帮助下,我学到并理解了一些非常有用的东西!同样在研究了这个来源之后:[[关于 XML 中的空白你需要知道什么]][1][1]

代码的行为可以通过解析器如何处理 XML DOM 中的空白来解释

在以下 XML DOM 中:

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
  <book category="cooking">
    <title lang="en">Everyday Italian</title>
    <author>Giada De Laurentiis</author>
    <year>2005</year>
    <price>30.00</price>
  </book>

很容易认为元素节点&lt;book&gt;有四个孩子,即四个元素&lt;title&gt;, &lt;author&gt;, &lt;year&gt; and &lt;price&gt;,但实际上它有7个孩子,因为解析器会处理每个元素后面的空白(回车+换行)节点作为空文本节点。

因此,正如 Anton 所展示的,该元素实际上有 7 个子元素:

child       Type
0           text node (or white space node)
1           element node <title>
2           text node
3           element node <author>
4           text node
5           element node <year>
6           text node
7           element node <price>

代码仅查找元素节点 (nodeType =1),因此仅继续处理if (y.nodeType == 1);

瞧,输出是:

1 title
3 author
5 year
7 price


  [1]: https://oracle.com/technical-resources/articles/wang-whitespace.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-11-23
    • 1970-01-01
    • 2020-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多