2012-07-06 3 views
3

특정 값을 찾으려고 시도하는 XML 파일을 구문 분석하려고합니다. 다음은 XML이다 : "foo는이 A0/A1/setting0/sequence0에서 15의 ​​값이"가변 중첩 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> 

데이터 : 덤퍼는

$VAR1 = { 
      'folder' => { 
         'id' => 'A0', 
         'folder' => { 
            'setting' => { 
               'sequence' => { 
                  'group' => { 
                     'variable' => { 
                         'value' => '15', 
                         'name' => 'foo' 
                        }, 
                     'name' => 'info' 
                     }, 
                  'id' => 'sequence0' 
                  }, 
               'id' => 'setting0' 
              }, 
            'id' => 'A1' 
           } 
        } 
     }; 

내 목표는 같은 것을 말한다 보고서입니다 생산하고 있습니다. 알림 id을 사용하여 foo의 위치에 대한 "탐색 경로"흔적을 나타냅니다.

현재 나는이 하나 이상의 <variable>가있는 경우 작동하지 않으며,이있을 것이다 그러나

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

(와이 예제 XML의 값 "15"에 접근 ...하지만 그건 나의입니다 내가 알고하지 않기 때문에 주요 도전 ...)

문제는 얼마나 깊은 것이 것이라고 XML이 <folder>의의 예측할 수없는 중첩을 포함 할 것이며, 나는 <variable>name="foo"에 존재하는 찾는 방법을 몰라 있다. foo의 복수 인스턴스가 발생하지만 각각 sequence에 대해 하나만 발생합니다.

마지막으로 작은 키커는 XML :: Simple 및 XML :: Parser에만 액세스 할 수 있다는 것입니다. SAX/Twig/LibXML 등은 없습니다. 그리고 XML 데이터 파일의 크기는 최대 100MB입니다.

이제 모든 것이 상당히 복잡해 보입니다. 즉, <variable>이있는 곳에서 name="foo"으로 XML을 탐색하고 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"; 
    } 

답변

1

당신이 XML :: 나뭇 가지를 설치할 수없는 어떤 이유가 있습니까? 이것은 순수한 Perl 모듈 (설치 한 XML :: Parser에 따라 다름)이므로 코드 디렉토리 , use myTwig; 및 voilà에 항상 Twig.pm 파일을 복사하여 배포 할 수 있습니다.

그런 다음 코드는 매우 간단하다 : 이것에 대한

#!/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> 
+0

감사합니다. 당신은 XML :: Twig의 설치가 너무 간단해서 (간단히 말해서 Twig.pm을 올바른 디렉토리에 두는 것만으로도) 제가 설득했습니다. 솔루션은 이미 분산 된 VM에 적용될 것이기 때문에 새로운 것을 설치하는 것을 꺼려했습니다. 따라서 최종 사용자를위한 지침에서 단순성을 찾고있었습니다. 위의 코드를 사용하여 구문 오류가'near '-> parse "'되었으므로 편집에 사소한 조정을 게시합니다. – dhigger

+0

oops, cut'n paste error! 나는'parse' 전에 쉼표를 추가했습니다. 이제 해결되었습니다. – mirod

관련 문제