问题描述
我使用XMLDOM + XPath在此脚本中查找XML节点:
var DOMParser = require("xmldom").DOMParser;
var xpath = require("xpath");
let data = `<start>
<b1 id="111"><c1 id="333">ccc</c1></b1>
<b1 id="222">bbb</b1>
</start>`;
let doc = new DOMParser().parseFromString(data);
let nodes = xpath.select("//b1",doc);
// let doc2 = new DOMParser().parseFromString(nodes[0].toString());
let doc2 = nodes[0];
console.log("doc2.toString: ",doc2.toString());
let nodes2 = xpath.select("b1",doc2);
console.log("nodes found by xpath 'b1': ",nodes2.toString());
if (nodes2.length > 0) {
console.log("id = " + nodes2[0].getAttribute("id"));
}
nodes2 = xpath.select("b1/c1",doc2);
console.log("nodes found by xpath 'b1/c1': ",nodes2.toString());
if (nodes2.length > 0) {
console.log("id = " + nodes2[0].getAttribute("id"));
}
nodes2 = xpath.select("c1",doc2);
console.log("nodes found by xpath 'c1': ",nodes2.toString());
if (nodes2.length > 0) {
console.log("id = " + nodes2[0].getAttribute("id"));
}
我要列出<b1>
个节点的列表,然后获取该节点的id值。
XPath模式b1/c1
不起作用,但c1
起作用。
如果我从子节点的搜索中更改
let doc2 = nodes[0];
搜索完整的XML文档
let doc2 = new DOMParser().parseFromString(nodes[0].toString());
b1/c1
模式的工作!
为什么b1/c1
在第一种情况下不起作用?
尝试:
echo "<b1 id=\"111\"><c1 id=\"333\">ccc</c1></b1>" | xmllint --xpath b1/c1 -
发现:
<c1 id="333">ccc</c1>
在普通XML上,xpath模式可以正常工作,为什么不在XMLDOM的子节点上呢?
或尝试:
https://www.freeformatter.com/xpath-tester.html#ad-output
解决方法
我要列出节点列表,然后获取节点的id值。
也就是说,您要列出id属性值的列表吗?
var DOMParser = require("xmldom").DOMParser;
var xpath = require("xpath");
let data = `<start>
<b1 id="111"><c1 id="333">ccc</c1></b1>
<b1 id="222">bbb</b1>
</start>`
let doc = new DOMParser().parseFromString(data);
let ids = xpath.select("//b1/@id",doc).map(attr => attr.value);
// -> ["333","222"]
最后一行的替代方法是:
let ids = xpath.select("//b1",doc).map(node => node.getAttribute('id'));
// -> ["333","222"]