2012-03-11 14 views
10

Quiero analizar un archivo XML usando Perl. Pude hacerlo utilizando el módulo XML :: Simple, pero ahora quiero comenzar a usar el módulo XML :: XPath en su lugar porque usa expresiones XPath. Por mi limitado conocimiento, creo que XPaths facilitará el análisis futuro, ¿verdad? Aquí está el código Perl que tengo hasta ahora:Perl, cómo analizar el archivo XML, xpath

use strict; 
use warnings; 
use XML::XPath; 

my $file = "data.xml"; 
my $path = XML::XPath->new(filename => $file); 

my $name = $path->find('/category/event/@name'); 
print $name."\n"; 

Mi pregunta es ¿cómo puedo separar cada atributo de nombre (categoría/eventos/@nombre) para que pueda realizar pruebas en cada valor que analizar. Por el momento, estoy obteniendo una gran cadena de datos analizados, mientras que quiero varias cadenas pequeñas que pueda probar. ¿Cómo puedo hacer esto? Gracias :-)

Respuesta

18

This review señala que XML::XPath no se ha actualizado desde 2003, y recomienda XML::LibXML lugar

use 5.010; 
use strict; 
use warnings; 
use XML::LibXML; 

my $dom = XML::LibXML->new->parse_file('data.xml'); 
for my $node ($dom->findnodes('/category/event/@name')) { 
    say $node->toString; 
} 

Ver XML::LibXML::Parser y XML::LibXML::Node.

+3

se le recomienda 'XML :: LibXML' porque usted lo sabe mejor, o porque creo que tiene una ventaja real sobre los' XML: : XPath'? Hasta donde yo sé, este último funciona bien. También es puro Perl, lo que lo hace más lento que LibXML pero utilizable sin la ayuda de una biblioteca externa. – Borodin

+3

Eso es un hipervínculo allá arriba. Síguelo – daxim

+0

@daxim Gracias por la respuesta. Intenté que funcionara, pero no al 100% como quería. Mi resultado es name = "attribute_value", pero solo quiero attribute_value. ¿Hay alguna manera de simplemente generar el attribute_value sin el nombre = ""? – liverpaul

7

El método find devuelve un objeto XML::XPath::NodeSet que es una colección de todos los nodos que se encuentran . No puedo imaginar lo que puede haber hecho para ver una cadena larga con todos los valores de los atributos.

Al recuperar el conjunto de nodos, trabajas en su contenido con métodos como size, get_node y get_nodelist (mira los documentos que he vinculado anteriormente). get_nodelist devolverá una lista Perl de, en este caso, XML::XPath::Node::Attribute objetos que también tienen sus propios métodos. Este programa debe empezar

use strict; 
use warnings; 

use XML::XPath; 

my $xp = XML::XPath->new(ioref => \*DATA); 

my $names = $xp->find('/category/event/@name'); 

for my $node ($names->get_nodelist) { 
    say $node->getNodeValue; 
} 


__DATA__ 
    <category name="a"> 
    <event name="cat1" /> 
    <event name="cat2" /> 
    <event name="cat3" /> 
    <event name="cat4" /> 
    <event name="cat5" /> 
    </category> 

SALIDA

cat1 
cat2 
cat3 
cat4 
cat5 
+0

Gracias por la respuesta. Después de leer el enlace publicado por daxim, he decidido usar XML :: LibXML en su lugar. Parece ser el mejor, así que como principiante, creo que sería mejor para mí aprender un módulo que esté mejor documentado. Aprecio la información de introducción que escribió, me ayudó a entender las cosas un poco mejor :-) – liverpaul

+0

usando 'XML :: XPath', ¿podemos usar'^'o' * 'dentro de la ruta ?. EX: 'my $ names = $ xp-> find ('/ category/eve *');' .Inside 'category', busque la etiqueta que comienza con' eve' – Venkatesh

Cuestiones relacionadas