4

假设我有一个这样的 HTML 树:

div
`- ul
   `- li          (*)
   `- li          (*)
   `- li          (*)
   `- li          (*)
      `- ul
         `- li
         `- li
         `- li

如何选择<li>标有 的元素(*)?它们是第一个<ul>元素的直接后代。

这是我找到第一个<ul>元素的方法:

my $ul = $div->look_down(_tag => 'ul');

现在我有了$ul,但是当我做类似的事情时:

my @li_elements = $ul->look_down(_tag => 'li');

它还查找<li>隐藏在 HTML 树中更深的元素。

如何仅找到作为第一个元素<li>的直接后代的<ul>元素?我的数量不详。(我不能像示例中那样只选择前 4 个)。

4

3 回答 3

8

您可以使用该方法获取HTML::Element对象的所有子节点,因此文档中第一个元素的所有子节点将是content_list<ul>

use HTML::TreeBuilder;

my $tree = HTML::TreeBuilder->new_from_file('my.html');

my @items = $tree->look_down(_tag => 'ul')->content_list;

但它的表现力要强得多HTML::TreeBuilder::XPath,它可以让您在文档中的任何位置找到元素子元素的所有子元素,就像<li>这样<ul><div>

use HTML::TreeBuilder::XPath;

my $tree = HTML::TreeBuilder->new_from_file('my.html');

my @items = $tree->findnodes('//div/ul/li')->get_nodelist;
于 2012-07-15T00:16:46.317 回答
5

如果你想使用 look_down 方法,你可以添加一个额外的条件来只获取孩子:

my @li_elements = $ul->look_down(_tag => 'li', sub {$_[0]->parent() == $ul});
于 2012-07-15T00:41:26.023 回答
0

为了使此页面完美完整,我将添加一个选项:

@li = grep { $_->tag() eq 'li' } $ul->content_list;

(其中 $ul 是您的顶级元素)

于 2016-12-08T23:28:18.530 回答