【问题标题】:Database created with perl stored as xml使用 perl 创建的数据库存储为 xml
【发布时间】:2011-07-02 17:07:33
【问题描述】:

我正在尝试将复杂的数组/哈希结构保存到 xml。 由于我对 perl 和 xml 都是新手,所以我不知道最简单的方法是什么。

所有的 xml 解析器、编写器、libxml 等模块都没有给我我想要的。 例如。 DumpXML 添加了很多标签。我尝试了许多不同的模块,但它们似乎都没有做我想要的,或者我不知道如何设置它们以便它们按我想要的方式工作。 也许我必须在较低级别上编写 xml 部分? 或者我最好不使用 perl 数据结构,而是直接将其存储到 xml?

这个想法是从 xml 数据创建一个 php 网页。 不幸的是,我也是一个 php 菜鸟,因此只是希望这样做不会是一个大问题。 :-) 我只是想要一个 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>

【问题讨论】:

  • 如果您正在寻找一个真正学习该主题的理由,而不是仅仅解决眼前的问题,这里有一本非常好的 OReilly 书,Perl 和 XML (oreilly.com/catalog/9780596002053)。这不是最新的孩子,但它很好地贯穿了这个话题。书中没有提到很多较新的模块,但它让你朝着正确的方向开始,并为你的构建奠定了良好的基础。

标签: xml perl data-structures


【解决方案1】:

您应该查看DBD::AnyData,看看它是否满足您的需求。它支持使用 XML 文件,就像使用 SQL 数据库一样。

【讨论】:

  • 感谢您的回答。我可以将此模块用作透明的xml访问是否正确。如果是,我可以使用my $content = adTie( 'XML', 'file.xml' ); 访问xml 文件吗?不幸的是,这并没有像我预期的那样工作:print Dumper $content; prints $VAR1 = { 'HASH(0x9d6d8a0)' =&gt; [] };
  • 对不起,我刚刚找到这个页面:vpservices.com/jeff/programs/AnyData/DBD-AnyData.html 我会看看它,然后再试试运气:-)
【解决方案2】:

我想建议您考虑使用 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。

【讨论】:

  • 嗯,我以前没听说过 YAML。但它看起来非常有趣且易于使用。我今晚会试试...谢谢!
  • 哇,我几乎不需要阅读任何内容。实现 yaml 非常简单 :-)
猜你喜欢
  • 2011-05-22
  • 2011-12-03
  • 2020-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-04
  • 2011-04-04
  • 1970-01-01
相关资源
最近更新 更多