【问题标题】:How to find just the direct descendants with HTML::TreeBuilder?如何使用 HTML::TreeBuilder 仅查找直系后代?
【发布时间】:2012-07-14 08:18:01
【问题描述】:

假设我有一个这样的 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');

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

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

【问题讨论】:

    标签: html perl parsing html-tree


    【解决方案1】:

    您可以使用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 更具表现力,它可以让您在文档中的任何位置找到<ul> 的所有<li> 子元素<div> 的子元素,就像这样

    use HTML::TreeBuilder::XPath;
    
    my $tree = HTML::TreeBuilder->new_from_file('my.html');
    
    my @items = $tree->findnodes('//div/ul/li')->get_nodelist;
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

        为了让这个页面完美完整,我再添加一个选项:

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

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

        【讨论】:

          猜你喜欢
          • 2012-04-30
          • 1970-01-01
          • 1970-01-01
          • 2014-10-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-17
          • 1970-01-01
          相关资源
          最近更新 更多