检测空的xml元素

时间:2014-05-30 09:13:44

标签: xml perl xml-parsing

我有以下代码来读取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

我该怎么做?

2 个答案:

答案 0 :(得分:2)

你不应该使用XML :: DOM,它老了,速度慢,维护得很差。请改用XML::LibXMLXML::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)

自2005年以来,

XML::DOM尚未更新或维护。错误跟踪器中的issues标记为10年前的重要内容。建议不要使用这个模块。

两个更好的选择是XML::TwigXML::LibXMLmirod已经提供了前者的实施。这是后者的一个:

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