如何使用HTML::TreeBuilder查找直接子级后代?

4
假设我有这样的HTML树:
div
`- ul
   `- li          (*)
   `- li          (*)
   `- li          (*)
   `- li          (*)
      `- ul
         `- li
         `- li
         `- li

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

以下是我如何查找第一个 <ul> 元素:

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

现在我有了$ul,但当我执行以下操作时:
my @li_elements = $ul->look_down(_tag => 'li');

它还可以找到HTML树中更深层次的<li>元素。
我如何只找到第一个<ul>元素的直接子级<li>元素?它们的数量是未知的。(不能像示例中选择前4个)
3个回答

8
您可以使用content_list方法获取HTML::Element对象的所有子节点,因此文档中第一个<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更具表现力,它可以让你在文档中任何地方查找所有<div>元素的子元素<ul>的子元素<li>,就像这样:

use HTML::TreeBuilder::XPath;

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

my @items = $tree->findnodes('//div/ul/li')->get_nodelist;

5
如果您想使用`look_down`方法,可以添加额外的条件来仅获取子元素:
my @li_elements = $ul->look_down(_tag => 'li', sub {$_[0]->parent() == $ul});

0
为了使这个页面完美无缺,我会添加一个选项:
@li = grep { $_->tag() eq 'li' } $ul->content_list;

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接