我是perl和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>
</results>
</book_reviewers>
<book_reviews>
<results>
<review id="1">
<title>First Book</title>
<reviewed_by>Anne</reviewed_by>
<rating>5</rating>
</review>
<review id="2">
<title>First Book</title>
<reviewed_by>Bob</reviewed_by>
<rating>3</rating>
</review>
<review id="3">
<title>Second Book</title>
<reviewed_by>Charlie</reviewed_by>
<rating>4</rating>
</review>
<review id="3">
<title>Second Book</title>
<reviewed_by>Anne</reviewed_by>
<rating>4</rating>
</review>
</results>
</book_reviews>
以下是我尝试过的一些代码
my $parser = new XML::LibXML;
print "Couldn't retrieve review details\n"
unless my $book_reviews = $parser->parse_file($reviews_file);
print "Couldn't retrieve critic details\n"
unless my $critic_details = $parser->parse_file($critics_file);
#extract the reviewers details and write to file
for my $critics ($critic_details->findnodes('/book_reviewers/results/reviewer')) {
#get each of the critic's details
my $name = $critics->findvalue('name');
my $profession = $critics->findvalue('profession');
for my $reviews($book_reviews->findnodes('book_reviews/results/review')){
my $reviewed_by = $reviews->findvalue('reviewed_by');
if ($reviewed_by eq $name ){
my $book = $reviews->findvalue('title');
my $rating = $reviews->findvalue('rating');
}
}
}
我想做的是:
遍历每个book_reviewer并获取名称。职业。
为每个book_reviewer完成评论并获取该book_reviewer的所有book_reviews并提取有关评论的详细信息。
它将显示在html表中,但我可以这样做,没问题。
目前它不会与$ Viewed_by和$ crit的值相匹配 - 但如果我有硬编码的$ crit值,即if($ review_by eq&#39; Anne&#39;)< / p>
我也试过
$byline->isSameNode($name );
$byline->isEqual($name );
以及
$query = "//review[bline/text() = $name ";
任何帮助表示赞赏 - (我无法安装任何其他模块 - 只能使用默认模块) 干杯
答案 0 :(得分:1)
我建议你打开警告并严格执行代码。
use warnings;
use strict;
如果你这样做,你会发现变量$ critic没有被定义。
对于各种perl问题,另一个非常有用的技巧是包含Data :: Dumper。
use Data::Dumper
然后你可以通过打印诸如
之类的东西来看看你拥有的东西print Dumper($critics);
最后,在使用您的代码后,我认为您的主要问题是您在查找节点的调用中使用的地址。
您使用'/book_reviewer/results/reviewer'
而非'/book_reviewers/results/reviewer'
进行的第一次通话以及使用'/result_set/results/review'
代替'/book_reviews/results/review'
进行的第二次通话。
我插入了这些内容,添加了一些打印语句以查看发生了什么,看起来它有效。
for my $critics ($critic_details->findnodes('/book_reviewers/results/reviewer')) {
#get each of the critic's details
my $name = $critics->findvalue('name');
print "Got Name: $name\n";
my $profession = $critics->findvalue('profession');
print "Got Profession: $profession\n";
for my $reviews ($book_reviews->findnodes('/book_reviews/results/review')){
print Dumper($reviews);
my $reviewed_by = $reviews->findvalue('reviewed_by');
print "Got reviewed_by: $reviewed_by\n";
print "Compare $reviewed_by with $name\n";
if ($reviewed_by eq $name ){
print "Bingo!\n";
my $book = $reviews->findvalue('title');
my $rating = $reviews->findvalue('rating');
}
}
}