将 XML 数据解析为不同的结构
Parsing XML data into a different structure
我有以下 XML 文件,我正在尝试解析它
<Books>
<book name="first" feed="contentfeed" mode="modes" />
<book name="first" feed="communityfeed" mode="modes" region="1"/>
<book name="second" feed="contentfeed" mode="" />
<book name="second" feed="communityfeed" mode="modes" />
<book name="second" feed="articlefeed" mode="modes" />
</Books>
我正在使用 Perl 5.8 版和 XML::Simple
。下面是我写的代码
use XML::Simple;
my $xs = new XML::Simple( KeyAttr => { book => 'name' } , ForceArray => [ 'book','name' ] );
my $config = $xs->XMLin( <complete path to xml file> );
下面是结果(使用Data::Dumper
显示)
'book' => {
'first' => {
'feed' => 'communityfeed',
'mode' => 'modes',
'region' => '1'
},
'second' => {
'feed' => 'articlefeed',
'mode' => 'modes'
},
}
相反,我希望输出格式如下
'book' => {
'first' => {
'communityfeed' => { mode => 'modes', region => '1' },
'contentfeed' => { mode => 'modes' }
},
'second' => {
'communityfeed' => { mode => 'modes' },
'contentfeed' => { mode => '' },
'articlefeed' => { mode => 'modes' }
},
}
备注
- 无法更改 XML 文件格式,因为它是当前生产版本
- 首选 Perl 5.8 版,因为这是父脚本中使用的版本,解析逻辑应合并到该脚本中
您以前遇到过这种问题吗?如果是这样,那么如何解决这个问题?
XML::Simple
是一个使用起来笨拙且令人沮丧的模块,我非常怀疑您是否可以说服它构建您需要的数据结构。几乎任何其他 XML 解析器都会向前迈出一步
这是一个使用 XML::Twig
的解决方案。您可以查询已解析的 XML 数据并从中构建您喜欢的任何数据结构
我使用 Data::Dump
只是为了显示结果数据
use strict;
use warnings 'all';
use XML::Twig;
my $config;
{
my $twig = XML::Twig->new;
$twig->parsefile('books.xml');
for my $book ( $twig->findnodes('/Books/book') ) {
my $atts = $book->atts;
my ( $name, $feed ) = delete @{$atts}{qw/ name feed /};
$config->{book}{$name}{$feed} = $atts;
}
}
use Data::Dump;
dd $config;
输出
{
book => {
first => {
communityfeed => { mode => "modes", region => 1 },
contentfeed => { mode => "modes" },
},
second => {
articlefeed => { mode => "modes" },
communityfeed => { mode => "modes" },
contentfeed => { mode => "" },
},
},
}
我有以下 XML 文件,我正在尝试解析它
<Books>
<book name="first" feed="contentfeed" mode="modes" />
<book name="first" feed="communityfeed" mode="modes" region="1"/>
<book name="second" feed="contentfeed" mode="" />
<book name="second" feed="communityfeed" mode="modes" />
<book name="second" feed="articlefeed" mode="modes" />
</Books>
我正在使用 Perl 5.8 版和 XML::Simple
。下面是我写的代码
use XML::Simple;
my $xs = new XML::Simple( KeyAttr => { book => 'name' } , ForceArray => [ 'book','name' ] );
my $config = $xs->XMLin( <complete path to xml file> );
下面是结果(使用Data::Dumper
显示)
'book' => {
'first' => {
'feed' => 'communityfeed',
'mode' => 'modes',
'region' => '1'
},
'second' => {
'feed' => 'articlefeed',
'mode' => 'modes'
},
}
相反,我希望输出格式如下
'book' => {
'first' => {
'communityfeed' => { mode => 'modes', region => '1' },
'contentfeed' => { mode => 'modes' }
},
'second' => {
'communityfeed' => { mode => 'modes' },
'contentfeed' => { mode => '' },
'articlefeed' => { mode => 'modes' }
},
}
备注
- 无法更改 XML 文件格式,因为它是当前生产版本
- 首选 Perl 5.8 版,因为这是父脚本中使用的版本,解析逻辑应合并到该脚本中
您以前遇到过这种问题吗?如果是这样,那么如何解决这个问题?
XML::Simple
是一个使用起来笨拙且令人沮丧的模块,我非常怀疑您是否可以说服它构建您需要的数据结构。几乎任何其他 XML 解析器都会向前迈出一步
这是一个使用 XML::Twig
的解决方案。您可以查询已解析的 XML 数据并从中构建您喜欢的任何数据结构
我使用 Data::Dump
只是为了显示结果数据
use strict;
use warnings 'all';
use XML::Twig;
my $config;
{
my $twig = XML::Twig->new;
$twig->parsefile('books.xml');
for my $book ( $twig->findnodes('/Books/book') ) {
my $atts = $book->atts;
my ( $name, $feed ) = delete @{$atts}{qw/ name feed /};
$config->{book}{$name}{$feed} = $atts;
}
}
use Data::Dump;
dd $config;
输出
{
book => {
first => {
communityfeed => { mode => "modes", region => 1 },
contentfeed => { mode => "modes" },
},
second => {
articlefeed => { mode => "modes" },
communityfeed => { mode => "modes" },
contentfeed => { mode => "" },
},
},
}