获取第N个元素的Perl XML :: LibXML

时间:2014-05-19 05:52:11

标签: xml perl xml-libxml

这是一些简化的示例xml

<book_reviewers>
    <results>
        <reviewer>
            <name>Anne</name>
            <profession>Catfish wrangler</profession>
        </reviewer>
        <reviewer>
            <name>Bob</name>
            <profession>Beer taster</profession>
        </reviewer>
        <reviewer>
            <name>Charlie</name>
            <profession>Gardener</profession>
        </reviewer>
        <reviewer>
            <name>Don</name>
            <profession>DoGooder</profession>
        </reviewer>
        <reviewer>
            <name>Ellie</name>
            <profession>Elephant Trainer</profession>
        </reviewer>
        <reviewer>
            <name>Freddy</name>
            <profession>Fencer</profession>
        </reviewer>
    </results>
</book_reviewers>

我解析数据

#!/usr/bin/perl
use XML::LibXML;
use strict;

my $filename = "cr.xml";

my $parser = XML::LibXML->new();
my $critic_details = $parser->parse_file("$filename") or die;

现在我想抓住随机评论员的详细信息

my $no_of_critics = ($critic_details->findvalue("count(/book_reviewers/results/reviewer)"));

我将1号和$ no_of_critics发送到子程序,该子程序返回1和$ no_of_critics之间的随机数(即n在这种情况下为1和6)

所有这一切都很好我只需要知道我如何告诉它哪个评论者 - 说它返回5,然后我怎么告诉它我想要第五次评论?我试过搜索,但是我找不到正确的搜索词,所以我有点卡住了

干杯

4 个答案:

答案 0 :(得分:0)

假设您获得5回报,那么您需要做的是迭代节点并保留一个计数器,该计数器在每次迭代时递增,如果计数器达到5,则可以打印出该节点的信息。

XML::LibXML::Node处查看findnodes

另见:

  1. perl script to iterate over xml nodes using XML::LibXML

  2. Iterating over nodes using XML::LibXML

答案 1 :(得分:0)

findnodes返回一个数组。您只需选择所需的数组索引:

use strict;
use warnings;

use XML::LibXML;

my $dom = XML::LibXML->load_xml(IO => \*DATA);

my @reviewers = $dom->findnodes('//reviewer');
print "Count = " . @reviewers . "\n";

my $i = int rand @reviewers;
my $record = $reviewers[$i];
print $record, "\n";

__DATA__
<book_reviewers>
    <results>
        <reviewer>
            <name>Anne</name>
            <profession>Catfish wrangler</profession>
        </reviewer>
...

答案 2 :(得分:0)

您可以使用指定列表中第n个元素的XPath表达式:

#!/usr/bin/perl
use warnings;
use strict;

use XML::LibXML;

my $filename = 'cr.xml';

my $parser         = 'XML::LibXML'->new();
my $critic_details = $parser->parse_file($filename) or die;
my $index          = 1 + int rand $critic_details->findvalue('count(/book_reviewers/results/reviewer)');
my $reviewer       = $critic_details->findnodes("/book_reviewers/results/reviewer[$index]");
print $reviewer;

请注意,XPath中的位置从1开始,与Perl中的数组索引的0不同。

答案 3 :(得分:0)

建立在上一个问题中已有的基础之上:

use strict;
use warnings;

use utf8;

use XML::LibXML;

my $filename = "cr.xml";

my $parser = XML::LibXML->new();
my $critic_details = $parser->parse_file("$filename") or die;

# find ALL the <book_reviewers><results><reviewers> nodes
my @reviewers = $critic_details
  ->findnodes("book_reviewers/results/reviewer");
die "no reviewer nodes in xml-file" unless @reviewers;

# @reviewers in scalar context gives the number of elements
my $reviewer = $reviewers[ rand @reviewers ];

printf "reviewer: %s (%s)\n",
  $reviewer->findvalue("name"),
  $reviewer->findvalue("profession"),
  ;

__END__

可能导致:

reviewer: Anne (Catfish wrangler)

享受!