2013-04-28 4 views
0

J'ai un XML et je veux imprimer tous ses nœuds et je veux accéder aux champs de nœuds de films.Parsing complexe XML en Perl

Je peux accéder à Nom et Ville, mais je ne peux pas accéder aux champs Film.

<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> 

code:

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"; 
} 
+1

XML :: Simple n'est pas recommandé, peut-être essayer quelque chose XML :: Parser basé serait mieux. – MkV

Répondre

0

Essayez que:

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"; 
} 

Fondamentalement, vous demandez de passer par le tableau de Cinema entrées dans votre xml, mais dans ce cas, car il y a seulement un d'entre eux, il est construit comme une seule valeur scalaire. L'option ForceArray indique à libray de considérer cette entrée comme un tableau à un élément, ou plus précisément, pour tout xml introduit dans le script, les balises Cinema seront toujours faites comme un tableau de balises, qu'il y en ait un ou plusieurs leur. Cette option peut prendre:

  • un tableau de noms de balises qui doivent être contraints de tableaux,
  • 1 pour le forcer à tous les tags,
  • 0 de ne pas l'utiliser (ce qui est la valeur par défaut)

Oh, et ajoutez une balise de fermeture OnlineCinema à la fin de votre fichier XML pour l'analyser correctement. XML :: Simple est l'analyseur XML le plus dur à utiliser.

3

J'utilise 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"); 
    } 
} 

(je suppose Cinéma peut avoir plus d'un Film, mais étant donné la présence de MovieName dans Cinéma, qui pourrait ne pas être le cas. Il va encore travailler si elle est pas le cas, mais vous pourriez vouloir éliminer la boucle interne for.)