如何使用HTML :: TreeBuilder找到直接后代?

bod*_*ydo 4 html perl parsing html-tree

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

div
`- ul
   `- li          (*)
   `- li          (*)
   `- li          (*)
   `- li          (*)
      `- ul
         `- li
         `- li
         `- li
Run Code Online (Sandbox Code Playgroud)

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

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

my $ul = $div->look_down(_tag => 'ul');
Run Code Online (Sandbox Code Playgroud)

现在我有了$ul,但是当我做的事情如下:

my @li_elements = $ul->look_down(_tag => 'li');
Run Code Online (Sandbox Code Playgroud)

它还会找到<li>隐藏在HTML树中更深层的元素.

我如何找到<li>第一个<ul>元素的直接后代的元素?我的数量不详.(我不能只选择前4个例子).

Bor*_*din 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;
Run Code Online (Sandbox Code Playgroud)

但它使用起来更具表现力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;
Run Code Online (Sandbox Code Playgroud)


Sno*_*rri 5

如果要使用look_down方法,可以添加额外的条件以仅获取子项:

my @li_elements = $ul->look_down(_tag => 'li', sub {$_[0]->parent() == $ul});
Run Code Online (Sandbox Code Playgroud)