2010-09-22 130 views
2

考慮到XML :: Simple是唯一可以使用的模塊,所以我被困在從XML中檢索值中。結構低於:如何使用Perl的XML :: Simple從XML文件提取值?

<testxml> 
    <dev> 
     <A> 
      <tables> 
       <datatables> 
        <table>a1</table> 
        <table>a2</table> 
        <table>a3</table> 
       </datatables> 
       <propertytables> 
        <table>A1</table> 
        <table>A2</table> 
       </propertytables> 
      </tables> 
     </A> 
     <B> 
      <tables> 
       <datatables> 
        <table>b1</table> 
        <table>b2</table> 
       </datatables> 
       <propertytables> 
        <table>B1</table> 
        <table>B2</table> 
       </propertytables> 
      </tables> 
     </B> 
    </dev> 
</testxml> 

的XMLOut是:

<opt> 
    <dev name="A"> 
    <tables name="datatables"> 
     <table>a1</table> 
     <table>a2</table> 
     <table>a3</table> 
    </tables> 
    <tables name="propertytables"> 
     <table>A1</table> 
     <table>A2</table> 
    </tables> 
    </dev> 
    <dev name="B"> 
    <tables name="datatables"> 
     <table>b1</table> 
     <table>b2</table> 
    </tables> 
    <tables name="propertytables"> 
     <table>B1</table> 
     <table>B2</table> 
    </tables> 
    </dev> 
</opt> 

如何檢索表陣列說這個條件:
dev名稱= 「B」 和表名= 「propertytables」 #輸出B1,B2

+3

爲什麼它是唯一可以使用的模塊? – Ether 2010-09-22 16:05:34

+0

我的老闆說在這種情況下XPath或任何其他模塊只是一個矯枉過正的情況:( – Abhishek 2010-09-22 17:39:20

+0

因此,你的老闆寧願讀整個文件並創建一個大的內存數據結構?:) – 2010-09-22 20:19:25

回答

3

XML :: Simple是這個角色唯一使用的模塊。對於這樣的事情,我會用一些XPath來使用XML :: LibXML。

但是,如果您想使用XML :: Simple,我發現最好的方法是使用Data :: Dumper轉儲XML :: Simple構建的數據結構,並使用該轉儲找出最佳方式走結構。就你而言,這很簡單。

#!/usr/bin/perl 

use strict; 
use warnings; 

use XML::Simple; 
use Data::Dumper; 

my $xml = do { local $/; <DATA> }; 

my $doc = XMLin($xml); 

# print Dumper $doc; 

my $dev = 'B'; 
my $table = 'propertytables'; 

foreach (@{$doc->{dev}{$dev}{tables}{$table}{table}}) { 
    print "$_\n"; 
} 

__END__ 
<opt> 
    <dev name="A"> 
    <tables name="datatables"> 
     <table>a1</table> 
     <table>a2</table> 
     <table>a3</table> 
    </tables> 
    <tables name="propertytables"> 
     <table>A1</table> 
     <table>A2</table> 
    </tables> 
    </dev> 
    <dev name="B"> 
    <tables name="datatables"> 
     <table>b1</table> 
     <table>b2</table> 
    </tables> 
    <tables name="propertytables"> 
     <table>B1</table> 
     <table>B2</table> 
    </tables> 
    </dev> 
</opt> 
+0

如何在單個實體上執行強制陣列?我正在嘗試這樣的事情:對於前者,如果對於dev「B」,如果「propertytables」具有單個表格,則將其視爲標量。 my $ config = XMLin('./ test.xml',forcearray => ['{dev} - > {B} - > {tables} - > {propertytables} - > {table}']);但我想這是一個錯誤的方式。 – Abhishek 2010-09-23 11:06:54

+0

哦,我知道了。我只需要指定forcearray => [qw(table)] – Abhishek 2010-09-23 16:20:10

2
$ref->{dev}{B}{tables}{propertytables}{table} 

將是參考和

@{ $ref->{dev}{B}{tables}{propertytables}{table} } 

將成爲列表。

但真正做

my $ref = XMLin($some_source); 
use Smart::Comments; 
### $ref 

# ... OR ... 

use Data::Dumper; 
print Data::Dumper->Dump([ $ref ], [ '*ref' ]); 

檢查結構看尋路會是怎樣。

相關問題