2012-03-11 13 views
10

Voglio analizzare un file XML utilizzando Perl. Sono stato in grado di farlo utilizzando il modulo XML :: Simple, ma ora voglio iniziare a utilizzare il modulo XML :: XPath perché utilizza le espressioni XPath. Dalla mia conoscenza limitata penso che gli XPath renderanno l'analisi del futuro più facile, giusto? Ecco il codice Perl che ho finora:Perl, come analizzare il file 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"; 

mia domanda è come faccio a separare ciascun attributo name (categoria/evento/@nome) in modo che possa effettuare test su ogni valore che di analisi. Al momento sto ottenendo solo una grande stringa piena di dati analizzati, mentre voglio parecchie piccole stringhe che posso testare. Come posso fare questo? Grazie :-)

risposta

18

This review ricorda che XML::XPath non è stato aggiornato dal 2003, e raccomanda XML::LibXML invece

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

Vedi XML::LibXML::Parser e XML::LibXML::Node.

+3

stai raccomandando 'XML :: LibXML' perché sai meglio, o perché si pensa che ha un vero e proprio vantaggio rispetto' XML: : XPath'? Per quanto ne so, quest'ultimo funziona bene. È anche puro Perl, che lo rende più lento di LibXML ma utilizzabile senza l'aiuto di una libreria esterna. – Borodin

+3

Questo è un hyperlink lassù. Seguilo. – daxim

+0

@daxim Grazie per la risposta. Ho provato che funzionava, ma non al 100% come volevo. Il mio output è name = "attribute_value", ma voglio solo attributo_valore. C'è un modo per emettere l'attributo value_value senza il nome = ""? – liverpaul

7

Il metodo restituisce un oggetto findXML::XPath::NodeSet che è una raccolta di tutti i nodi trovati . Non riesco a immaginare cosa si possa fare per vedere una lunga stringa con tutti i valori degli attributi.

Dopo aver recuperato il set di nodi, si lavora sui suoi contenuti con metodi come size, get_node e get_nodelist (vedere i documenti che ho collegato sopra). get_nodelist restituirà un elenco Perl di, in questo caso, gli oggetti XML::XPath::Node::Attribute che hanno anche i propri metodi. Questo programma dovrebbe iniziare

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> 

USCITA

cat1 
cat2 
cat3 
cat4 
cat5 
+0

Grazie per la risposta. Dopo aver letto il link postato da daxim ho deciso invece di utilizzare XML :: LibXML. Sembra essere il migliore là fuori, quindi come principiante penso che sarebbe meglio per me imparare un modulo che è meglio documentato. Apprezzo le informazioni introduttive che hai scritto, mi ha aiutato a capire meglio le cose :-) – liverpaul

+0

usando 'XML :: XPath', possiamo usare'^'o' * 'all'interno del percorso ?. EX: 'my $ names = $ xp-> find ('/ category/eve *');' .Inside 'category', cerca tag che inizia con' eve' – Venkatesh