Reputation: 121
I am a complete newbie at perl and xml
I have data from two sources. One is book reviewers and their details, the other is reviews/
I need to get each reviewer, then for each reviewer get all of their reviews.
here is a simplified version of the data:
<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>
Here is some code that i have tried
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');
}
}
}
What I am trying to do is:
Iterate through each book_reviewer and get name. profession.
For each book_reviewer got through the reviews and get all book_reviews for that book_reviewer and extract details about the reviews.
It will be displayed in a html table but i can do that, no problem.
At the moment it won't match the value of $reviewed_by and $critic - but it will if I had hard code the $critic value i.e. if ($reviewed_by eq 'Anne')
I have also tried
$byline->isSameNode($name );
$byline->isEqual($name );
and also
$query = "//review[bline/text() = $name ";
Any help appreciated - (and I cannot install any other modules - can only use the default ones) Cheers
Upvotes: 0
Views: 495
Reputation: 4396
I suggest you turn on warnings and strict in your code.
use warnings;
use strict;
If you do that you will notice that the variable $critic is not being defined.
Another really useful trick for all kinds of perl problems is to include Data::Dumper.
use Data::Dumper
Then you can see what you have by printing stuff such as
print Dumper($critics);
Finally, after playing with your code a bit I think your main problem is the addresses you are using in your call to find nodes.
The first call you are using '/book_reviewer/results/reviewer'
instead of '/book_reviewers/results/reviewer'
and the second call you are using '/result_set/results/review'
instead of '/book_reviews/results/review'
.
I plugged those in, added some print statements to see what was happening and it looks like it works.
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');
}
}
}
Upvotes: 1