考虑以下代码
const cheerio = require('cheerio');
const xml = `<foo id="1" a="blah"><updateHistory><foo id="1" a="blah"/><foo id="1" a="blah"/><foo id="1" a="blah"/><foo id="1" a="blah"/></updateHistory>Figs. 1-9</foo>`;
const $ = cheerio.load(xml, { normalizeWhitespace: true, xmlMode: true }, false);
const elements = $('foo');
const num = elements.length;
if (num) console.log(num); // prints 5 because there are 5 'foo' tags
但我不想要
<updateHistory></updateHistory>
标签内的任何内容。换句话说,我希望 element
仅包含第一个 <foo>
标签,并且 num
为 1。我该怎么做?
更新:所以,事实证明我可以做这样的事情
for (let i = 0, j = elements.length; i < j; i++) {
if (elements[i].parent.name !== 'updateHistory') {
// this is the tag I want
}
}
有更好的办法吗?
你建议的方法很好。写得简洁一点:
const elements = [...$("foo")]
.filter(e => e.parent.name !== "updateHistory");
如果
<foo>
是传递后代,而不是直接子代,则此操作将会失败。如果您需要处理这个问题,您可以一路遍历树来检查是否存在 <updateHistory>
祖先:
const cheerio = require("cheerio"); // 1.0.0-rc.12
const xml = `
<foo id="1" a="blah">
<updateHistory>
<bar>
<foo id="1" a="blah"/>
<foo id="1" a="blah"/>
<foo id="1" a="blah"/>
<foo id="1" a="blah"/>
</bar>
</updateHistory>
Figs. 1-9
</foo>`;
const $ = cheerio.load(xml, {xml: true});
const elements = [...$("foo")]
.filter(e => {
for (; e; e = e.parent) {
if (e.name === "updateHistory") {
return false;
}
}
return true;
});
console.log(elements.length); // => 1
这是另一种方法:
const xml = `
<foo id="1" a="blah">
<updateHistory>
<foo id="1" a="blah"/>
<foo id="1" a="blah"/>
<foo id="1" a="blah"/>
<foo id="1" a="blah"/>
</updateHistory>
Figs. 1-9
</foo>`;
const $ = cheerio.load(xml, {xml: true});
const elements = [...$("foo")]
.filter(e => $(e).find("updateHistory").length);
console.log(elements.length); // => 1
这表示“获取所有具有
<foo>
后代的 <updateHistory>
”。