我有以下代码来读取XML文件,其中包含
中的以下元素<byline>name</byline>
<display_title>title</display_title>
<mpaa_rating>PG</mppa_rating>
我有以下perl代码来浏览xml文档并打印出上述元素的值
use XML::DOM;
my $doc;
my $parser = new XML::DOM::Parser;
die "Unable to parse XML document\n"
unless $doc = $parser->parsefile ("../reviews.xml");
foreach $elem ($doc->getElementsByTagName ("review")) {
foreach $review($elem->getChildNodes){
foreach $child ($review->getChildNodes) {
if($review->getTagName eq 'byline'){#name of tag
print $child->getNodeValue."->";
}
if($review->getTagName eq 'display_title'){#name of tag
print $child->getNodeValue."->";
}
if($review->getTagName eq 'mpaa_rating'){#name of tag
print $child->getNodeValue.";\n";
}
}
}
}
发生的问题是,如果找到一个空元素,程序将继续在同一行上打印。例如,当程序达到<mpaa_rating/>
时,输出将是
name->title->name
。如果找到评级,我希望程序打印name->title->no Rating
。
我该怎么做?
答案 0 :(得分:2)
你不应该使用XML :: DOM,它老了,速度慢,维护得很差。请改用XML::LibXML或XML::Twig。
代码与XML :: LibXML非常相似。你只需要在上一次测试中添加一个else:
if($review->getTagName eq 'mpaa_rating'){#name of tag
print $child->getNodeValue.";\n";
}
else {
print "no;\n";
}
使用XML :: Twig,这是代码:
#!/usr/bin/perl
use strict;
use warnings;
use 5.10.0;
use XML::Twig;
XML::Twig->new( twig_handlers => { review => \&review, })
->parse( \*DATA); # replace with ->parsefile( 'file.xml') to parse a file
sub review
{ my( $t, $review)= @_;
my @values;
foreach my $field ( qw( byline display_title mpaa_rating))
{ push @values, $review->field( $field) || 'no'; }
say join( "->", @values), ";";
}
__DATA__
<doc>
<review>
<byline>name</byline>
<display_title>title</display_title>
<mpaa_rating>PG</mpaa_rating>
</review>
<review>
<byline>name 1</byline>
<display_title>title 1</display_title>
<mpaa_rating/>
</review>
</doc>
答案 1 :(得分:1)
XML::DOM
尚未更新或维护。错误跟踪器中的issues
标记为10年前的重要内容。建议不要使用这个模块。
两个更好的选择是XML::Twig
和XML::LibXML
。 mirod
已经提供了前者的实施。这是后者的一个:
use strict;
use warnings;
use XML::LibXML;
my $dom = XML::LibXML->load_xml(IO => \*DATA);
for my $review ($dom->findnodes('//review')) {
my @values = map {$review->findvalue($_) || 'no'} qw(byline display_title mpaa_rating);
print join("->", @values), "\n";
}
__DATA__
<root>
<review>
<byline>name</byline>
<display_title>title</display_title>
<mpaa_rating>PG</mpaa_rating>
</review>
<review>
<byline>name 1</byline>
<display_title>title 1</display_title>
<mpaa_rating/>
</review>
</root>
输出:
name->title->PG
name 1->title 1->no