3

特定の値を見つけようとして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です」のようなレポートです。idsを使用して、の場所への「パンくず」トレイルを参照したいことに注意してください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"foosequence

最後のちょっとしたキッカーは、私が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";
  }
4

1 に答える 1

1

XML :: Twigをインストールできない理由はありますか?これは純粋なPerlモジュール(インストールしたXML :: Parserに依存します)であるため、コードディレクトリTwig.pmのようにディストリビューションからファイルをいつでもコピーできます。myTwig.pmuse myTwig;

次に、コードは非常に単純です。

#!/usr/bin/perl

use myTwig;


XML::Twig->new( twig_handlers => { 'variable[@name="foo"]' => \&variable,
                                   # next line if you need to reduce memory footprint
                                   group => sub { $_->purge; }, 
                                 }
         ->parse( \*DATA); # replace with parsefile( 'my.xml') for the real data

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";
  }

__DATA__
<?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>
于 2012-07-06T15:42:15.323 に答える