2011-07-02 30 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