在Perl中解析复杂的XML

时间:2013-04-28 21:36:31

标签: xml perl parsing

我有一个XML,我想打印他的所有节点,我想访问电影节点字段。

我可以访问姓名和城市,但我无法访问电影字段。

<OnlineCinema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Cinema.xsd">
<Cinema>
    <City>Cluj</City>
    <Name>Cinema2</Name>
    <MovieName>ScaryMovie</MovieName>
    <Movie>
        <Name>ScaryMovie</Name>
        <Genre>comedie</Genre>
        <Director>lala</Director>
        <Writer>asdf</Writer>
        <Cast>asdvvb</Cast>
        <Year>2010</Year>
        <Trailer>http://www.youtube.com/embed/RMDZ8M47j0I</Trailer>
        <NRLoc>400</NRLoc>
    </Movie>
</Cinema>

代码:

use XML::Simple;
use Data::Dumper;

$xml = new XML::Simple (KeyAttr=>[]);
$data = $xml->XMLin("OnlineCinema.xml");
print "Content-type: text/html \n\n";

foreach $e (@{$data->{Cinema}}) {
    print "City: ", $e->{City}, "</br>\n";
    print "Name: ", $e->{Name}, "</br>\n"; 
    print "</br></br>\n";
}

2 个答案:

答案 0 :(得分:3)

XML :: Simple是最难使用的XML解析器。我使用XML :: LibXML。

use strict;
use warnings;

use XML::LibXML qw( );

my $parser = XML::LibXML->new();
my $doc = $parser->parse_file('OnlineCinema.xml');

for my $cinema ($doc->findnodes('/OnlineCinema/Cinema')) {
   my $cinema_name = $cinema->find('Name');
   my $cinema_city = $cinema->find('City');

   for my $movie ($cinema->findnodes('Movie')) {
      my $movie_name  = $movie->find('Name');
      my $movie_genre = $movie->find('Genre');

      print("$movie_name ($movie_genre) is playing at the $cinema_name in $cinema_city\n");
   }
}

(我假设 Cinema 可以有多个电影,但 Cinema 中存在 MovieName >,情况可能并非如此。如果情况不是这样,它仍然有效,但您可能想要消除内部for循环。)

答案 1 :(得分:0)

试试:

use XML::Simple qw(:strict);
use Data::Dumper;

$xml = new XML::Simple (KeyAttr => [], ForceArray => [qw( Cinema )]);
$data = $xml->XMLin("OnlineCinema.xml");

print "Content-type: text/html \n\n";

foreach $e (@{$data->{Cinema}}) {
    print "City: ", $e->{City}, "<br/>\n";
    print "Name: ", $e->{Name}, "<br/>\n"; 
    print "<br/><br/>\n";
}

基本上,您要求遍历xml中的Cinema条目数组,但在这种情况下,由于只有其中一个条目,因此它构建为单个标量值。 ForceArray选项告诉libray将该条目视为一个元素数组,或者更确切地说,对于任何提供给脚本的xml,Cinema标记将始终作为一个数组标签,无论是一个还是多个。该选项可能需要:

  • 必须强制使用数组的标记名称数组
  • 1强制它加入所有代码,
  • 0不使用它(这是默认设置)

哦,并在xml的末尾添加一个结束OnlineCinema标记,以便正确解析。