cheeriojs 选择不在另一个指定标签内的标签

问题描述 投票:0回答:1

考虑以下代码

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

有更好的办法吗?

node.js cheerio
1个回答
0
投票

你建议的方法很好。写得简洁一点:

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

© www.soinside.com 2019 - 2024. All rights reserved.