2016-04-19 2 views
0

У меня есть пример HTML:Синтаксических Вложенные элементы HTML :: TreeBuilder

<div> 
    <p>get this</p> 
</div> 
<p>not this</p> 

Есть ли способ, чтобы получить вложенный элемент, используя HTML::TreeBuilder и look_down? Я могу использовать look_down на результирующем элементе первого поиска.

my $tree = HTML::TreeBuilder->new; 
$tree->parse("<div><p>get this</p></div><p>not this</p>"); 
my $div = $tree->look_down(_tag => "div"); 
my $p = $div->look_down(_tag => "p"); 
print $p->as_text() . "\n"; 

Можно ли получить это в одном поиске, похожий на селектор CSS div p? Я ограничен XPath?

+0

Почему вы хотите использовать look_down В таком случае, XPATH или CSS селекторов будет удобно?. Если вы используете HTML :: TreeBuilder :: XPath, тогда вы можете выполнить 'my $ p = $ tree-> findnodes ('// div/p') -> [0];'. И если вы предпочитаете HTML :: TreeBuilder :: Select: 'my $ p = ($ tree-> select ('div p')) [0];'. – Dada

+0

То, что первоначально привлекло меня к 'look_down', - это скорость и XPath. Я обнаружил, что это 7 раз медленнее на моей машине, используя этот скрипт: https://gist.github.com/dsullivan7/6d039fda561d6bf4d55e4b8fd8f7a6c3 –

ответ

1

Вы можете look_up форма все p «s, чтобы увидеть, что они содержатся ли в div:

#!/usr/bin/perl 
use warnings; 
use strict; 
use feature qw{ say }; 

use HTML::TreeBuilder; 

sub paragraph_whose_ancestor_is_div { 
    my $node = shift; 
    return 'p' eq $node->{_tag} && $node->look_up(_tag => 'div') 
} 

my $tree = 'HTML::TreeBuilder'->new; 
$tree->parse("<html><div><p>get this</p></div><p>not this</p></html>"); 

my @p = $tree->look_down(\&paragraph_whose_ancestor_is_div); 

say $_->as_text() for @p; 
+1

Это действительно просто то, что предложил OP, но назад и скрывает второй поиск внутри подпрограммы. Вы также проверяете, является ли какой-либо * предком * 'div', а не только * parent *. Ответ заключается в том, что нет, нет одношагового решения. – Borodin

+0

Чтобы проверить только родителя, вы можете вместо этого использовать '' div 'eq ($ node-> lineage_tag_names) [0] '. Я согласен, что это не идеально (мне нравится XPath больше). – choroba

+0

Да, и, к счастью, DOM, кажется, умирает, за исключением LibXML. CSS имеет преимущество перед XPath для HTML5 в том, что он будет анализировать значения атрибутов класса «class», разделенные пробелами, но, возможно, XPath 2 делает это? – Borodin

Смежные вопросы