perl xml :: libxml findvalue匹配

时间:2014-05-17 03:55:46

标签: xml perl libxml2 string-matching

我是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');
                }
        }
}

我想做的是:

  1. 遍历每个book_reviewer并获取名称。职业。

  2. 为每个book_reviewer完成评论并获取该book_reviewer的所有book_reviews并提取有关评论的详细信息。

  3. 它将显示在html表中,但我可以这样做,没问题。

    目前它不会与$ Viewed_by和$ crit的值相匹配 - 但如果我有硬编码的$ crit值,即if($ review_by eq&#39; Anne&#39;)< / p>

    我也试过

    $byline->isSameNode($name );
    $byline->isEqual($name );
    

    以及

    $query = "//review[bline/text() = $name ";
    

    任何帮助表示赞赏 - (我无法安装任何其他模块 - 只能使用默认模块) 干杯

1 个答案:

答案 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');
            }
    }
}