HTML :: Treebuilder - Разбор между родителями - PullRequest
1 голос
/ 06 октября 2010

Люди,

В HTML :: Treebuilder так много информации, что я удивлен, что не могу найти ответ, надеюсь, я не просто упускаю его.

То, что я пытаюсь сделать, - это просто анализ между родительскими узлами, поэтому, имея HTML-документ, подобный этому

<html>
<body>
   <a id="111" name="111"></a>
   <p>something</p>
   <p>something</p>
   <p>something</p>
   <a href=xxx">something</a>
   <a id="222" name="222"></a>
   <p>something</p>
   <p>something</p>
   <p>something</p>
   ....
 </body>
 </html>

Я хочу иметь возможность получить информацию об этом 1-ом теге привязки (111), затем обработать 3 p-тега и затем получить следующий тег привязки (222), а затем обработать эти p-теги и т. Д. И т. Д.

Легко добраться до каждого тега привязки

use HTML::TreeBuilder;
my $tree = HTML::TreeBuilder->new();
$tree->parse_file("index-01.htm");
foreach my $atag ( $tree->look_down( '_tag', 'a' ) ) {
    if ($atag->attr('id')) {
        # Found 'a' tag, now process the p tags until the next 'a'
    }
}

Но как только я найду этот тег, как мне получить все теги p до следующей привязки?

ТИА !!

1 Ответ

4 голосов
/ 06 октября 2010

HTML :: TreeBuilder версия

#!/usr/bin/perl

use strict; use warnings;
use HTML::TreeBuilder;

my $tree = HTML::TreeBuilder->new;

$tree->parse_file(\*DATA);
$tree->elementify;
$tree->objectify_text;

foreach my $atag ( $tree->look_down( '_tag', 'a' ) ) {
    if ($atag->attr('id')) {
        printf "Found %s\n", $atag->as_XML;
        process_p( $atag );
    }
}

sub process_p {
    my ($tag) = @_;
    while ( defined( $tag ) and defined( my $next = $tag->right ) ) {
        last if lc $next->tag eq 'a';
        if ( lc $next->tag eq 'p') {
            $next->deobjectify_text;
            print $next->as_text, "\n";
        }
        $tag = $next;
    }
}

__DATA__
<html>
<body>
   <a id="111" name="111"></a>
   <p>something</p>
   <p>something</p>
   <p>something</p>sometext
   <a href=xxx">something</a>
   <a id="222" name="222"></a>
   <p>something</p>
   <p>something</p>
   <p>something</p>
 </body>
 </html>

Вывод:

Found <a id="111" name="111"></a>

something
something
something
Found <a id="222" name="222"></a>

something
something
something

HTML :: TokeParser :: Простая версия

#!/usr/bin/perl

use strict; use warnings;
use HTML::TokeParser::Simple;

my $parser = HTML::TokeParser::Simple->new(\*DATA);

while ( my $tag = $parser->get_tag('a') ) {
    next unless $tag->get_attr('id');
    printf "Found %s\n", $tag->as_is;
    process_p($parser);
}

sub process_p {
    my ($parser) = @_;
    while ( my $next = $parser->get_token ) {
        if ( $next->is_start_tag('a') ) {
            $parser->unget_token($next);
            return;
        }
        elsif ( $next->is_start_tag('p') ) {
            print $parser->get_text('/p'), "\n";
        }
    }
    return;
}

Вывод:

Found <a id="111" name="111">
something
something
something
Found <a id="222" name="222">
something
something
something
...