如何将XML提取并转换为Perl数据结构
我的文件夹中有xml文件,我需要从xml文件中提取一些信息并存储在散列中如何将XML提取并转换为Perl数据结构,xml,perl,Xml,Perl,我的文件夹中有xml文件,我需要从xml文件中提取一些信息并存储在散列中 <?xml version="1.0" encoding="UTF-8"?> <Servicemodule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <Service Id="478" Name="Pump Motor"> <Description>It delivers actual pump speed</
<?xml version="1.0" encoding="UTF-8"?>
<Servicemodule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<Service Id="478" Name="Pump Motor">
<Description>It delivers actual pump speed</Description>
<ServiceCustomers>
<SW Service="SKRM" Path="/work/hr_service.xml"/>
</ServiceCustomers>
<ServiceSuppliers>
<HW Type="s" Nr="12" Service="1" Path="/work/hardware.xml"/>
<HW Type="v" Nr="2" Service="1" Path="/work/hardware.xml"/>
<HW Type="mt" Nr="1" Service="1" Path="/work/hardware.xml"/>
</ServiceSuppliers>
</Service>
</Servicemodule>
我无法创建哈希,因为我想使用上述脚本。请帮助我脚本如何获取属性值并存储在这样的散列中
我们需要这样做
use strict;
use warnings;
use feature ':5.10';
use XML::Twig;
use File::Find;
my $num=0;
my %combeh;
my $dir="V:/Main/work";
find(\&wanted, $dir);
sub wanted() {
if ( -f and /(_service\.xml)$/) {# find all the files with a suffix of .xml
my $tweak_server =sub{
my @bhi;
my ($twig, $root) =@_;
my $code=$root->first_child_text('Service Id');
my $ser=$root->first_child('ServiceCustomers');
my $ser_cnt=$root->first_child_text('SW');
my $ser1=$root->first_child('ServiceSuppliers');
my $ser1_cnt=$root->first_child_text('HW');
if ($ser){
push (@bhi, $ser->toString,$File::Find::name);
$combeh{$code}=[@bhi];
}
if ($ser1){
push (@bhi, $ser1->toString,$File::Find::name);
$combeh{$code}=[@bhi];
};
my $roots = { Service => 1 };
my $handlers = { 'Servicemodule/Service' => $tweak_server,
};
my $twig = new XML::Twig(TwigRoots => $roots,
TwigHandlers => $handlers,
pretty_print => 'indented'
);
$twig->parsefile($_);
}
}
return (%combeh) ;
}
'478'=>[
{
Description='It delivers actual pump speed'
}
{
Service='SKRM',
Path='/work/hr_service.xml'
}
{
Type='s'.
Nr='12',
Service='s',
path='/work/hardware.xml'
}
{
Type='v'.
Nr='2',
Service='s',
path='/work/hardware.xml'
}
{
Type='mt'.
Nr='1',
Service='1',
path='/work/hardware.xml'
}
...
...
....
请帮我解决这个问题
提前谢谢
听了你的建议,我试着这样做
#!/usr/bin/perl
use warnings;
use strict;
use XML::Simple;
use Carp;
use File::Find;
use File::Spec::Functions qw( canonpath );
use Data::Dumper;
my @ARGV ="C:/Main/work";die "Need directories\n" unless @ARGV;
find(
sub {
return unless ( /(_service\.xml)$/ and -f );
extract_information();
return;
},
@ARGV
);
sub extract_information {
my $path= $_;
my $xml=XMLin($path);
my $xml_services = $xml->{Service};
my %services;
for my $xml_service (@$xml_services) {
my %service = (
description => $xml_service->{Description},
name => $xml_service->{Name},
id => $xml_service->{Id},
);
$service{sw} = _maybe_list( $xml_service->{ServiceCustomers}{SW} );
$service{hw} = _maybe_list( $xml_service->{ServiceSuppliers}{HW} );
$service{sw} = _maybe_list( $xml_service->{ServiceSuppliers}{SW} );
$services{ $service{id} } = \%service;
}
print Dumper \%services;
}
sub _maybe_list {
my $maybe = shift;
return ref $maybe eq 'ARRAY' ? $maybe : [$maybe];
}
感谢您的回复,我是XML::Simple的新手,我学习了该模块,理解了您的脚本。但当我运行你们的代码时,我在for循环行中遇到了类似“notarray Reference”的错误。我尝试了不同的方法来克服这个错误,但仍然是相同的错误。有时,我在ServiceSuppliers中具有软件和硬件属性。因此,我又添加了一行与您的格式相同的内容。我有一个问题,你说“如果XML中只有一个元素,它将不会被包装”,但在ServiceCustomers中,有时我只有一个元素具有一些属性,如XML文件中所示。可以吗?或者我该怎么办?你能帮我解决这些问题吗
请任何人帮我解决这个错误。如果XML文件不是太大,您可以使用更简单的方法进行转换 Simple的优点是,它比XML更方便地操作Perl数据结构 缺点是它会消耗更多的内存,因为它必须将整个XML文件加载到内存中。它对XML中的大小写也很敏感
use strict;
use warnings;
use XML::Simple;
use Data::Dumper;
process_service_xml(shift);
sub process_service_xml {
my $xml = XMLin(shift);
# Illustrating what you've got after XML::Simple processes it.
print "******* XML::Simple input ********\n";
print Dumper $xml;
print "**********************************\n";
# Pull out the Services
my $xml_services = $xml->{Service};
# Iterate through each Service to transform them
my %services;
for my $xml_service (@$xml_services) {
# Pull out the basic information
my %service = (
description => $xml_service->{Description},
name => $xml_service->{Name},
# Redundant with the key, but useful to keep all the data about the
# service in one place.
id => $xml_service->{Id},
);
# Get SW and HW as their own attributes.
# If there's a single element in the XML it won't be wrapped in
# an array, so make sure each are a list.
$service{sw} = _maybe_list( $xml_service->{ServiceCustomers}{SW} );
$service{hw} = _maybe_list( $xml_service->{ServiceSuppliers}{HW} );
# Store the service in the larger hash, keyed by the ID.
$services{ $service{id} } = \%service;
}
# And here's what the information has been transformed into.
print "******* Services ********\n";
print Dumper \%services;
print "*************************\n";
}
sub _maybe_list {
my $maybe = shift;
return ref $maybe eq 'ARRAY' ? $maybe : [$maybe];
}
L7a
来自哪里?为什么XML中的“<代码>路径/<代码>值设置在输出中?<代码> ---/COD>?请修复您的缩进,并在每隔一行后删除空白行。在脚本中,我有小错误和小疑惑,你能看一看我编辑的问题吗?因为我按照你说的做了尝试,但我有一个小错误,我展示了我在你的建议后所做的尝试。请您帮助解决此问题。我正在寻求您的帮助,请帮助我。@verendra 1“非数组引用”即将到来,因为XML文档没有服务条目,所以$XML\u services
为空。在这种情况下,您应该将其初始化为空数组ref,或者从例程返回。2) 您的额外软件条目比上一个条目快。使用push
向其追加。3) \u列表
可能会处理服务客户
或服务供应商
只有一个条目的情况。您可以在第一个数据转储中看到它。我将把修复代码留给您来编写,这开始有点像“为我编写代码”。