我有一個文件夾中的XML文件,我需要提取從XML文件和存儲的一些信息在hash.My XML文件看起來像這樣如何提取和轉換XML到Perl數據結構
<?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>
我想將這些信息保存在一個像服務Id這樣的散列中,作爲密鑰和擴展信息作爲該密鑰的散列值數組。服務客戶和供應商元素中的軟件和硬件屬性都是散列鍵值(服務ID)的數組值。它對於專家來說很容易,但我是新學習者,所以這個問題讓我苦惱。 我試過這樣
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) [email protected]_;
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 ::簡單,我研究了模塊和我理解你的腳本。但是當我運行你的代碼時,我得到了錯誤,如「不是數組引用」for循環line.I嘗試以不同的方式來克服這一點,但仍然是相同的錯誤。有時我在ServiceSuppliers中有SW和HW屬性。所以我再添加一行與你的格式相同。我有一個問題,你說:「如果XML中有單個元素,它將不會被包裹」,但有時在ServiceCustomers中,我只有一個元素,像我在xml文件中顯示的那樣具有一些屬性。是否可以?或者我應該怎麼做?你能幫我解決這些問題嗎?
請任何人幫我解決這個錯誤。
'L7a'從哪裏來?爲什麼在你的輸出中XML中設置了各種'Path'值,但是是''''? – CanSpice
請修復您的縮進,並在每隔一行後刪除空行。 – ikegami