特定の値を見つけようとしてXMLファイルを解析しようとしています。XMLは次のとおりです。
<?xml version="1.0"?>
<dump>
<folder id="A0">
<folder id="A1">
<setting id="setting0">
<sequence id="sequence0">
<group name="info">
<variable name="foo" value="15"/>
</group>
</sequence>
</setting>
</folder>
</folder>
</dump>
Data::Dumperは
$VAR1 = {
'folder' => {
'id' => 'A0',
'folder' => {
'setting' => {
'sequence' => {
'group' => {
'variable' => {
'value' => '15',
'name' => 'foo'
},
'name' => 'info'
},
'id' => 'sequence0'
},
'id' => 'setting0'
},
'id' => 'A1'
}
}
};
私の目標は、「fooの値はA0 / A1 / settings0/sequence0で15です」のようなレポートです。id
sを使用して、の場所への「パンくず」トレイルを参照したいことに注意してくださいfoo
。
現在、この例のXMLの値「15」にアクセスします。
use strict;
use warnings;
use XML::Simple;
my $xml = new XML::Simple;
my $data = $xml -> XMLin('test1.xml');
print $data -> {folder}{folder}{setting}{sequence}{group}{variable}{value};
(ただし、複数ある場合は機能しません<variable>
。また、存在する可能性があります...しかし、それは私の主な課題ではありません...)
問題は、XMLに予測できないsのネストが含まれることです。また、の深さがわからないため、がどこに存在する<folder>
かを見つける方法がわかりません。の複数のインスタンスが発生しますが、それぞれに1つだけです。<variable>
name="foo"
foo
sequence
最後のちょっとしたキッカーは、私がXML::SimpleとXML::Parserにのみアクセスできることです!SAX / Twig/LibXMLなどはありません。XMLデータファイルのサイズは最大100MBです。
これらはすべて非常に複雑に聞こえるので、目標を言い換えます。XMLが<variable>
存在する場所をトラバースし、ツリー内のname="foo"
その場所と場所を報告します。value
これについて助けてくれてありがとう。
編集:以下のmirodの方法を使用して、これが機能したものです:
use strict;
use warnings;
use Twig;
my $twig = new XML::Twig(
twig_handlers =>
{ 'variable[@name="foo"]' => \&variable,
group => sub { $_->purge; } }
);
$twig->parsefile( "test.xml");
sub variable
{ my( $t, $var)= @_;
my $location= join '/', grep { $_ } map { $_->id } reverse $var->ancestors;
print $var->att( 'name'), " has value ", $var->att( 'value'), " at $location\n";
}