2016-08-08 20 views
1

Hallo allerseits ich bin ein neuer Perl-Programmierer und ich versuche jetzt, einige Daten aus einer langen XML-Datei zu holen. Aber ich kann die beiden Daten im Allgemeinen nicht gleichzeitig mit meinem Code abrufen, bitte muss ich prüfen, wie man effizient eine Schleife oder irgendeine Struktur verwendet, um die Daten zu bekommen, die ich brauche.Parsing in einer langen XML-Datei mit Perl

<item> 
    <datetime>7/28/2016 12:00:00 AM - 12:00:15 AM</datetime> 
    <datetime_raw>42579.1668402778</datetime_raw> 
    <value channel="Traffic Total (volume)" channelid="1">4,664,204 KByte</value> 
    <value_raw channel="Traffic Total (volume)" channelid="1">4776145337.3504</value_raw> 
    <value channel="Traffic Total (speed)" channelid="1">517,319 kbit/s</value> 
    <value_raw channel="Traffic Total (speed)" channelid="1">64664843.4518</value_raw> 
    <value channel="Traffic DL (volume)" channelid="2">3,805,763 KByte</value> 
    <value_raw channel="Traffic DL (volume)" channelid="2">3897101197.8596</value_raw> 
    <value channel="Traffic DL (speed)" channelid="2">422,107 kbit/s</value> 
    <value_raw channel="Traffic DL (speed)" channelid="2">52763352.2591</value_raw> 
    <value channel="Traffic UL (volume)" channelid="3">858,442 KByte</value> 
    <value_raw channel="Traffic UL (volume)" channelid="3">879044139.4907</value_raw> 
    <value channel="Traffic UL (speed)" channelid="3">95,212 kbit/s</value> 
    <value_raw channel="Traffic UL (speed)" channelid="3">11901491.1927</value_raw> 
    <coverage>100 %</coverage> 
    <coverage_raw>0000010000</coverage_raw> 
    </item> 

Ich habe hundrends von Elementen wie diese, und ich brauche das Paar Datatime und den spezifischen Wert channel = „Traffic Total (Volumen)“ zur gleichen Zeit extrac, hier einen Auszug aus meinem Perl-Code:

my $reader = XML::LibXML::Reader->new(string => "$HDF") or die "cannot read file.xml\n"; 

while ($reader->nextElement('item')) { 
        my $item = $reader->readInnerXml; 
        while ($reader->nextElement('datetime')) { 
         $DT = $reader->readInnerXml; 
         print $DT; 

         while ($reader->nextElement('value')) { 
          my $value = $reader->readInnerXml; 
          if ($value eq 'Traffic Total (speed)'){ 
           $HD = $reader->readInnerXml; 
           print $HD; 
          } 
         } 
        } 
       } 

Danke für Ihre Kommentare dazu.

Antwort

0

Für lange XML, finde ich XML::Twig wirklich es hat gut - es twig_handers und purge verwenden können, wie Sie das Parsen, so dass Sie effizient Teilmengen von XML verarbeiten kann.

Also vorausgesetzt, Sie durch „Punkt“ gehen wollen, sind:

#!/usr/bin/env perl 

use strict; 
use warnings; 

use XML::Twig; 

my @things = ('./datetime', './value[@channel="Traffic Total (speed)"]'); 

sub process_item { 
    my ($twig, $item) = @_;  
    print join "\t", (map { $item -> get_xpath($_,0) -> text } @things),"\n"; 
    $twig->purge; 
} 

my $twig = XML::Twig -> new (twig_handlers => { 'item' => \&process_item }); 
    $twig -> parsefile ('your_file.xml'); 

Welche purge hat sich entledigen ‚bis zu diesem Punkt‘ aus dem Gedächtnis, so dass es sehr effizient für XML eine große Anzahl von ähnlichen enthält Elemente.

+0

Ich habe den Code angewendet, den Sie mir vorschlagen, aber das Ergebnis war die ganze XML-Datei, und wie ich Ihnen sagte, brauche ich nur die beiden genannten Daten, danke für Ihre Antwort :) –

+0

Dieser Code arbeitete mit dem abgeschnittenen du hast zur Verfügung gestellt. Was meinst du mit "all die XML-Datei"? – Sobrique