2011-09-19 75 views
2

我需要從XML文件中獲取一些值......該文件位於多個站點中..例如:http://1.1.1.1/apache2-default/status.xml,http://1.1.1.2/apache2-default/status.xml等等。XML文件的格式是:XML使用XML解析Perl :: Twig

<?xml version="1.0"?> 
<gateway> 
<version>Kannel bearerbox version `1.4.3' </version> 
<status>running, uptime 0d 14h 19m 49s</status> 
<wdp> 
<received><total>0</total><queued>0</queued></received> 
<sent><total>0</total><queued>0</queued></sent> 
</wdp> 
<sms> 
<received><total>50569</total><queued>0</queued></received> 
<sent><total>38</total><queued>0</queued></sent> 
<storesize>-1</storesize> 
<inbound>1.53,1.52,0.98</inbound> 
<outbound>0.00,0.00,0.00</outbound> 
</sms> 
<smscs><count>5</count> 
<smsc> 
<name>SMPP:1.2.3.4:3802/3802:hng123:HNDSMPP</name> 
<id>hng123</id> 
<status>online 51589s</status> 
<received>0</received> 
<sent>0</sent> 
<failed>0</failed> 
<queued>0</queued> 
</smsc> 
<smsc> 
<name>SMPP:1.2.3.4:3757/3757:vashn:HNDSMPP</name> 
<id>vas1</id> 
<status>online 51589s</status> 
<received>40872</received> 
<sent>32</sent> 
<failed>0</failed> 
<queued>0</queued> 
</smsc> 
</smscs> 
</gateway> 

這裏是代碼...我創建...

#!/usr/bin/perl -w 
use strict; 
use warnings; 

use XML::Twig; 
use Data::Dumper; 
use LWP::Simple; 

my $download_dir= "/root/lab_xml_perl/v2/Script_perl/bajados"; 
my @ips_server = ("192.168.246.129", "192.168.246.130"); 
for my $servers (@ips_server) { 
my $bajo = getstore("http://$servers/apache2-default/status.xml", "$download_dir/status.xml"); 

my $file = "$download_dir/status.xml"; 
my $twig = XML::Twig->new(); 
$twig->parsefile($file); 

my $root = $twig->root->first_child('smscs'); 

for my $connection ($root->children){ 
my $nombre_server = $connection->first_child_text('name'); 
my $id_server = $connection->first_child_text('id'); 
my $status_server = $connection->first_child_text('status'); 
my @status_gral = split(/\s+/, ${status_server}); 
my $recibidos_msg_server = $connection->first_child_text('received'); 
my $enviados_msg_server = $connection->first_child_text('sent'); 
my $encolados_msg_server = $connection->first_child_text('queued'); 
my $fallidos_msg_server = $connection->first_child_text('failed'); 
print "miId.String.id = Tabla_$id_server\n"; 
print "stringProp.String = $nombre_server\n"; 
print "idProp = $id_server\n"; 
print "status_idObs.StringObservation.obs = $status_gral[0]\n"; 
print "recvTotal.Metric = $recibidos_msg_server\n"; 
print "sentTotal.Metric = $enviados_msg_server\n"; 
print "queuedTotal.Metric = $encolados_msg_server\n"; 
print "faildTotal.Metric = $fallidos_msg_server\n"; 

} 
} 

然而運行腳本的時候,我得到的開頭有一些空字段...並警告.. 。每個xml文件從每個服務器... 這裏是輸出...爲什麼?...我不需要th em ...只需要與XML相關的字段..

miId.String.id = Tabla_ 
stringProp.String = 
idProp = 
Use of uninitialized value $status_gral[0] in concatenation (.) or string at ./v25.pl line 32. 
status_idObs.StringObservation.obs = 
recvTotal.Metric = 
sentTotal.Metric = 
queuedTotal.Metric = 
faildTotal.Metric = 
miId.String.id = Tabla_hng123 
stringProp.String = SMPP:1.2.3.4:3802/3802:hng123:HNDSMPP 
idProp = hng123 
status_idObs.StringObservation.obs = online 
recvTotal.Metric = 0 
sentTotal.Metric = 66173 
queuedTotal.Metric = 0 
faildTotal.Metric = 0 
miId.String.id = Tabla_vas1 
stringProp.String = SMPP:1.2.3.4:3757/3757:vashn:HNDSMPP 
idProp = vas1 
status_idObs.StringObservation.obs = online 
recvTotal.Metric = 0 
sentTotal.Metric = 45492 
queuedTotal.Metric = 0 
faildTotal.Metric = 0 
Use of uninitialized value $status_gral[0] in concatenation (.) or string at ./v25.pl line 32. 
status_idObs.StringObservation.obs = 
recvTotal.Metric = 
sentTotal.Metric = 
queuedTotal.Metric = 
faildTotal.Metric = 
miId.String.id = Tabla_hng123 
stringProp.String = SMPP:1.2.3.4:3802/3802:hng123:HNDSMPP 
idProp = hng123 
status_idObs.StringObservation.obs = online 
recvTotal.Metric = 0 
sentTotal.Metric = 0 
queuedTotal.Metric = 0 
faildTotal.Metric = 0 
miId.String.id = Tabla_vas1 
stringProp.String = SMPP:1.2.3.4:3757/3757:vashn:HNDSMPP 
idProp = vas1 
status_idObs.StringObservation.obs = online 
recvTotal.Metric = 40872 
sentTotal.Metric = 32 
queuedTotal.Metric = 0 
faildTotal.Metric = 0 

非常感謝您的幫助。

Michael。

回答

2

未初始化值的原因是因爲smscs中的第一個子項實際上是count

<smscs> 
    <count>5</count> 
    <smsc> 
     <name>SMPP:1.2.3.4:3802/3802:hng123:HNDSMPP</name> 
     <id>hng123</id> 
     <status>online 51589s</status> 
     <received>0</received> 
     <sent>0</sent> 
     <failed>0</failed> 
     <queued>0</queued> 
    </smsc> 
    <smsc> 
     <name>SMPP:1.2.3.4:3757/3757:vashn:HNDSMPP</name> 
     <id>vas1</id> 
     <status>online 51589s</status> 
     <received>40872</received> 
     <sent>32</sent> 
     <failed>0</failed> 
     <queued>0</queued> 
    </smsc> 
</smscs> 

因此,而不是讓的smscs所有的孩子,你只需要拿到smsc孩子:

foreach my $connection ($root->children('smsc')) { 
    ... 
} 
以我的經驗
+1

,'$ elt->兒童()'(或'FIRST_CHILD ',或者真正的任何導航方法)幾乎總是一個錯誤。你應該通過使用一個條件來限制導航,除非你真的有很好的理由不這樣做(並且你測試了你在下面的代碼中訪問的元素)。 – mirod

+0

恩,非常感謝。代碼和建議,邁克爾。 –

+0

@mirod你會建議使用'children'導航的替代方法嗎? – stevenl