0

我需要解析一个xml 文件,我在 perl 僧侣网站上找到了这段代码,我无法理解代码,我需要的是能够访问哈希数组元素。

use Data::Dumper;
use XML::Rules;


my $parser = XML::Rules->new(
    stripspaces => 7,
    rules => {
        substrate => sub { 'substrate' => $_[1]->{id}},
        product => sub { '@products' => $_[1]->{id}},
        reaction => sub {
            my %reactions;
            foreach (split / /, $_[1]->{name}) {
                $reactions{$_} = { substrate => $_[1]->{substrate}, products => $_[1]->{products}};
            }
            return '%reactions' => \%reactions;
        },
        graphics => '',
        entry => sub {
            my @reactions = split ' ', (delete $_[1]->{reaction});
            $_[1]->{reactions} = \@reactions if @reactions;
            return '%entries' => {$_[1]->{id} => $_[1]}
        },
        pathway => 'pass'
    });


    print Dumper ($parser->parsefile('ko00010.xml'));  
4

2 回答 2

2

您很可能不想将大型 XML 文件转换为 Perl 数据结构。这很容易,但处理数据的方式非常愚蠢(XML 不能很好地映射到现代动态语言的数据结构,反之亦然):

use XML::Simple qw(XMLin);
use File::Slurp qw(read_file);
use Data::Dumper qw(Dumper); 
print Dumper XMLin scalar(read_file 'kegg.xml'),
    KeyAttr => undef, ForceArray => 1, StrictMode => 1;

相反,学习 XPath 并访问您实际需要的元素:

use XML::LibXML qw();
my $xml = XML::LibXML->load_xml(location => 'kegg.xml');
for ($xml->findnodes('//entry[@name="cpd:C00103"]')) {
    print $_->getAttribute('link');
}
于 2013-07-12T07:46:42.570 回答
-1

对...所以您不想将大型 XML 文件转换为 Perl 数据结构,因此您使用一个库,该库从整个文件构建自己的数据结构,然后使用另一种语言搜索该混乱。这有多蠢?

如果文件确实很大(原始发帖人没有说),您需要部分处理 XML。虽然可以使用 SAX(如果您碰巧在被迫使用 Java 和 XML::LibXML::SAX、XML::SAX、XML::SAX::Base、XML 的文档进行编程时学习了 SAX ::Several::More::To::Study, ... 对你有任何意义),我建议忽略“官方”方式并使用 XML::Twig 或 XML::Rules。

第一个允许您指定包含您感兴趣的块的标签,并以易于吞咽的方式为您提供 XML(如果您愿意的话,还支持 XPath),并让您在使用后立即丢弃这些块已经完成了。

后者允许您指定要忽略的标签、从其他标签构建的数据结构、解析特定标签(包括其内容)后运行的代码等。这样您就可以构建一个专门的、精简的数据结构无需将整个文档保存在内存中,或者从 XML 的某些部分构建一个专门的、精简的数据结构,并在它们完成后立即处理这些部分。

如果您不关心内存占用并且只希望从 XML 中提取一些位,那么 LibXML 和 XPath 是正确的选择。另一方面,如果您需要大部分数据,您可能会发现 XML::Rules 更快。您对其进行设置,它会将 XML 转换为易于使用的结构,甚至可以在构建数据结构时计算或获取数据。

如果 XML 的六个是/成为问题,那么不要把你所有的东西扔出窗外,一直到 SAX 事件和处理程序中的一堆副作用,你应该考虑从 XML 切换:: LibXML 到 XML::Twig 并通过对代码的极少更改来处理这些块。或者,如果您使用 XML::Rules 来构建数据结构,请更改一两个规则,以便它处理数据而不是传递它们。

于 2013-07-12T18:02:17.713 回答