2012-05-01 4 views
8

Penso che questo sia un problema molto semplice, ma non riesco a capirlo nonostante molte ricerche.Script Perl per analizzare XML usando XML :: LibXML;

Sto cercando di analizzare il seguente XML per stampare qualcosa di simile a TAG = VALUE, in modo che possa scrivere questo in un file CSV. Il problema è che i tag non sono sempre gli stessi per ogni campione. Non riesco a capire come ottenere i nomi dei tag reali. Qualsiasi aiuto apprezzato !!!

XML File -

<Statistics> 
    <Stats> 
    <Sample> 
     <Name>System1</Name> 
     <Type>IBM</Type> 
     <Memory>2GB</Memory> 
     <StartTime>2012-04-26T14:30:01Z</StartTime> 
     <EndTime>2012-04-26T14:45:01Z</EndTime> 
    </Sample> 

    <Sample> 
     <Name>System2</Name> 
     <Type>Intel</Type> 
     <Disks>2</Disks> 
     <StartTime>2012-04-26T15:30:01Z</StartTime> 
     <EndTime>2012-04-26T15:45:01Z</EndTime> 
     <Video>1</Video> 
    </Sample> 
    </Stats> 
</Statistics> 

Script -

#!/usr/bin/perl 
use XML::LibXML; 

$filename = "data.xml"; 

my $parser = XML::LibXML->new(); 
my $xmldoc = $parser->parse_file($filename); 

for my $sample ($xmldoc->findnodes('/Statistics/Stats/Sample')) { 

print $sample->nodeName(), ": ", $sample->textContent(), "\n"; 

} 

risposta

16

Hai il giusto metodo per ottenere i nomi dei tag, basta un ciclo in più per correre attraverso i tag all'interno di ogni <sample>:

#!/usr/bin/perl 

use strict; 
use warnings; 

use XML::LibXML; 

my $filename = "data.xml"; 

my $parser = XML::LibXML->new(); 
my $xmldoc = $parser->parse_file($filename); 

for my $sample ($xmldoc->findnodes('/Statistics/Stats/Sample')) { 
    for my $property ($sample->findnodes('./*')) { 
     print $property->nodeName(), ": ", $property->textContent(), "\n"; 
    } 
    print "\n"; 
} 

Modifica: ho ora creato un sito tutorial chiamato Perl XML::LibXML by Example che risponde esattamente a questo tipo di domanda.

5

È necessario scorrere i figli del nodo Campione,

for my $sample ($xmldoc->findnodes('/Statistics/Stats/Sample')) { 
    print $sample->nodeName(), "\n"; 
    foreach my $child ($sample->getChildnodes) { 
     if ($child->nodeType() == XML_ELEMENT_NODE) { 
      print "\t", $child->nodeName(), ":", $child->textContent(), "\n"; 
     } 
    } 
} 

mostrerà,

Sample 
     Name:System1 
     Type:IBM 
     Memory:2GB 
     StartTime:2012-04-26T14:30:01Z 
     EndTime:2012-04-26T14:45:01Z 
Sample 
     Name:System2 
     Type:Intel 
     Disks:2 
     StartTime:2012-04-26T15:30:01Z 
     EndTime:2012-04-26T15:45:01Z 
     Video:1 
+2

Linea 3 + 4 + 6 può essere sostituito con: 'foreach my $ bambino ($ campione -> findnodes ('*')) {' – ikegami

+0

Grazie, fantastico !! – lozwell