Предоставляет ли Mojo :: DOM возможность использовать вложенный синтаксис? - PullRequest
3 голосов
/ 21 декабря 2011

Как я могу написать этот пример с модулем Mojo :: DOM?

#!/usr/bin/env perl
use warnings;
use 5.012;
use XML::LibXML;

my $string =<<EOS;
<result>
    <cd>
    <artists>
        <artist class="1">Pumkinsingers</artist>
        <artist class="2">Max and Moritz</artist>
    </artists>
    <title>Hello, Hello</title>
    </cd>
    <cd>
    <artists>
        <artist class="3">Green Trees</artist>
        <artist class="4">The Leons</artist>
    </artists>
    <title>The Shield</title>
    </cd>
</result>
EOS
#/
my $parser = XML::LibXML->new();
my $doc = $parser->load_xml( string => $string );
my $root = $doc->documentElement;

my $xpath = '/result/cd[artists/artist[@class="2"]]/title';

my @nodes = $root->findnodes( $xpath );
for my $node ( @nodes ) {
    say $node->textContent;
}

Ответы [ 2 ]

5 голосов
/ 21 декабря 2011

Mojo :: DOM поддерживает CSS3-селекторы, которые удивительны, но не так универсальны, как xpath; CSS3 не предоставляет способ подняться после спуска в узел.

Вы можете сделать то же самое, хотя это немного сложнее:

Mojo::DOM->new($string)
  ->find('result:root > cd > artists > artist.2')
  ->each(sub { say shift->parent->parent->title->text });

или

say $_->parent->parent->title->text
  for Mojo::DOM->new($string)
    ->find('result:root > cd > artists > artist.2')->each;
3 голосов
/ 21 декабря 2011

Хм, разве это не очевидно из http://search.cpan.org/perldoc/Mojo::DOM#SYNOPSIS?

use Mojo::DOM;
my $string =<<EOS;
<result>
    <cd>
    <artists>
        <artist class="1">Pumkinsingers</artist>
        <artist class="2">Max and Moritz</artist>
    </artists>
    <title>Hello, Hello</title>
    </cd>
    <cd>
    <artists>
        <artist class="3">Green Trees</artist>
        <artist class="4">The Leons</artist>
    </artists>
    <title>The Shield</title>
    </cd>
</result>
EOS
my $dom  = Mojo::DOM->new ($string );
my $xpath = '/result/cd[artists/artist[@class="2"]]/title';
print "\n1 ", $dom->find( $xpath );
print "\n2 ", $dom->find( '.2' );
print "\n3 ", $dom->find( 'artist.2' );
print "\n4 ", $dom->find( 'artists artist.2' );
print "\n5 ", $dom->find( 'artists artist.2' )->[0]->parent;
print "\n6 ", $dom->find( 'artists artist.2' )->[0]->parent->parent;
print "\n7 ", $dom->find( 'artists artist.2' )->[0]->parent->parent->find('title');
print "\n8 ", $dom->find( 'artists artist.2' )->[0]->parent->parent->find('title')->[0]->text;
print "\n9 ", $dom->find( 'artists artist.2' )->[0]->parent->parent->find('title')->first->text;
$dom->find( 'artists artist.2' )->each(sub {
    print  "\n10 ", $_[0]->parent->parent->find('title')->first->text;
});
__END__

1
2 <artist class="2">Max and Moritz</artist>
3 <artist class="2">Max and Moritz</artist>
4 <artist class="2">Max and Moritz</artist>
5 <artists>
        <artist class="1">Pumkinsingers</artist>
        <artist class="2">Max and Moritz</artist>
    </artists>
6 <cd>
    <artists>
        <artist class="1">Pumkinsingers</artist>
        <artist class="2">Max and Moritz</artist>
    </artists>
    <title>Hello, Hello</title>
    </cd>
7 <title>Hello, Hello</title>
8 Hello, Hello
9 Hello, Hello
10 Hello, Hello
...