2011-07-02 23 views
3

我試圖將複雜的數組/散列結構保存到xml。 因爲我是新的perl和xml我不知道什麼是最簡單的方法來做到這一點。用perl創建的數據庫存儲爲xml

所有的XML解析器,作家,libxml等模塊不給我我想要的。 例如DumpXML添加了很多標籤。我已經嘗試了很多不同的模塊,但是他們都沒有做我想做的事情,或者我不知道如何設置它們,以便它們按照我的意願工作。 也許我必須在較低的級別上編寫xml部分? 或者,如果我不使用perl數據結構,但直接將其存儲到xml是最好的?

這個想法是從xml數據創建一個php網頁。 不幸的是我也是一個PHP的noob,因此只是希望這樣做不會是一個大問題。 :-) 我只是想像下面的例子那樣有一個xml文件的邏輯佈局。

下面是我用Data::DiverXML::Smart來試用它的方法。

#!/usr/bin/perl 
use strict; 
use warnings; 
use Data::Dumper; 
use Data::Diver qw(Dive DiveRef DiveVal DiveError); 
use XML::Smart; 

my $content = {}; 

# Usage: add_content_entry(name, group, descr) 
sub add_content_entry { 
    my $name = shift; 
    my $group = shift; 
    my $descr1 = shift; 
    my $descr2 = shift; 

    my $data = { 
    DESCR1 => $descr1, 
    DESCR2 => $descr2, 
    }; 

    my @pos = split('/', $group); 
    push @pos, $name; 
    DiveVal($content, @pos) = $data; 
} 

sub xml_read { 
    my $xml = XML::Smart->new('file.xml'); 
    $content = $xml->data; 
} 

sub xml_write { 
    my $xml = XML::Smart->new(
    q` 
     <?xml version="1.0" encoding="iso-8859-1" ?> 
     <content></content> 
    `); 
    $xml->{content} = $content; 
    $xml->('file.xml'); 
} 

# Main 
&xml_read; # file.xml is empty 

&add_content_entry('content.1', 'group.A', 'Hello', 'World'); 
&add_content_entry('content.2', 'group.B/group.x', 'Fred', 'Flintstone'); 
&add_content_entry('content.3', 'group.B/group.y', 'bla', 'blah'); 
&add_content_entry('content.4', 'group.B/group.y', '???', '!!!'); 
&add_content_entry('content.5', 'group.C/group.z', '...', '...'); 

&xml_write; # file.xml is written 
$content = {}; 
&xml_read; # justify that file.xml can be read 
print Dumper $content; 

輸出應該是:

$VAR1 = { 
      'group.A' => { 
         'content.1' => { 
              'DESCR2' => 'World', 
              'DESCR1' => 'Hello' 
             } 
         }, 
      'group.C' => { 
         'group.z' => { 
             'content.5' => { 
                 'DESCR2' => '...', 
                 'DESCR1' => '...' 
                 } 
             } 
         }, 
      'group.B' => { 
         'group.y' => { 
             'content.3' => { 
                 'DESCR2' => 'blah', 
                 'DESCR1' => 'bla' 
                 }, 
             'content.4' => { 
                 'DESCR2' => '!!!', 
                 'DESCR1' => '???' 
                 } 
             }, 
         'group.x' => { 
             'content.2' => { 
                 'DESCR2' => 'Flintstone', 
                 'DESCR1' => 'Fred' 
                 } 
             } 
         } 
     }; 

我的問題是等級的數量不是爲不同的內容相同。

在xml文件中應該是這樣的(我知道排序是任意的,我保持與輸出print Dumper相同)。

<?xml version="1.0" encoding="iso-8859-1" ?> 
<content> 
    <group.A> 
    <content.1> 
     <DESCR2>World</DESCR> 
     <DESCR1>Hello</DESCR1> 
    </content.1> 
    </group.A> 
    <group.C> 
    <group.z> 
     <content.5> 
     <DESCR2>...</DESCR> 
     <DESCR1>...</DESCR1> 
     </content.5> 
    </group.z> 
    </group.C> 
    <group.B> 
    <group.y> 
     <content.3> 
     <DESCR2>blah</DESCR> 
     <DESCR1>bla</DESCR1> 
     </content.3> 
     <content.4> 
     <DESCR2>!!!</DESCR> 
     <DESCR1>???</DESCR1> 
     </content.4> 
    </group.y> 
    <group.x> 
     <content.2> 
     <DESCR2>Flintstone</DESCR> 
     <DESCR1>Fred</DESCR1> 
     </content.2> 
    </group.x> 
    </group.B> 
</content> 

<?xml version="1.0" encoding="iso-8859-1" ?> 
<content> 
    <group.A> 
    <content DESCR2="World" DESCR1="Hello">content.1</content> 
    </group.A> 
    <group.C> 
    <group.z> 
     <content DESCR2="..." DESCR1="...">content.5</content> 
    </group.z> 
    </group.C> 
    <group.B> 
    <group.y> 
     <content DESCR2="blah" DESCR1="bla">content.3</content> 
     <content DESCR2="!!!" DESCR1="???">content.4</content> 
    </group.y> 
    <group.x> 
     <content DESCR2="Flintstone" DESCR1="Fred">content.2</content> 
    </group.x> 
    </group.B> 
</content> 
+0

如果您正在尋找一個真正學習該主題的理由,而不僅僅是解決眼前的問題,那麼還有一本很好的OReilly書籍Perl和XML(http://oreilly.com/catalog/9780596002053/)。這不是該街區最新的孩子,但它是一個很好的主題。本書中沒有提到很多新模塊,但它可以讓您從正確的方向開始,併爲您打下良好的基礎。 – DavidO

回答

1

你應該看看DBD::AnyData,看看它是否符合您的需求。它支持以與SQL數據庫相同的方式使用XML文件。

+0

感謝您的回答。我可以使用這個模塊作爲透明的xml訪問是否正確?如果是的話,我可以用'my $ content = adTie('XML','file.xml');''來訪問xml文件。不幸的是,這不符合我的預期:'print Dumper $ content;'print'$ VAR1 = { 'HASH(0x9d6d8a0)'=> [] };' – Powderking

+0

對不起我剛剛發現這個網頁:http: //www.vpservices.com/jeff/programs/AnyData/DBD-AnyData.html 我會看看它,並再次嘗試我的運氣:-) – Powderking

1

我想建議您考慮使用YAML作爲XML的替代方案。正如你所說,XML往往會因標籤而變得臃腫。 YAML輸出更清晰,並且被設計爲可被人讀取。

所以你的數據輸出可能是這個樣子:

group.A: 
    content.1: 
    - DESCR2: World 
    - DESCR1: Hello 
    group.C: 
    group.z: 
     content.5: 
     - DESCR2: ... 
     - DESCR1: ... 
    group.B: 
    - group.y: 
    - content.3: 
     - DESCR2: blah 
     - DESCR1: bla 
    - content.4: 
     - DESCR2: !!! 
     - DESCR1: ??? 
    - group.x: 
     content.2: 
     - DESCR2: Flintstone 
     - DESCR1: Fred 

在Perl中,你可以使用YAML :: XS模塊。有PHP模塊也可以識別YAML。

+0

嗯,我沒有聽說過YAML。但它看起來非常有趣並且易於使用。我今天晚上會試試...謝謝! – Powderking

+0

哇,我幾乎沒有讀過任何東西。實現yaml非常簡單:-) – Powderking