2012-01-09 81 views
1

如何處理perl XML :: SAX模塊中的重複元素名稱?以下是我的xml文件:Perl:使用XML處理重複元素名稱:: SAX

<employees> 
    <employee> 
     <name>John</name> 
     <age>gg</age> 
     <department>Operations</department> 
     <amount Ccy="EUR">100</amount> 
     <company> 
      <name> abc </name> 
     </company> 
    </employee> 
    <employee> 
     <name>Larry</name> 
     <age>45</age> 
     <department>Accounts</department> 
     <amount Ccy="EUR">200</amount> 
     <company> 
      <name> xyz </name> 
     </company> 
    </employee> 
</employees> 

我的問題是如何訪問元素employees->員工 - >公司 - >名字? (我應該能夠打印「abc」和「xyz」),我這樣問的原因是因爲員工 - >員工 - >名稱中還有一個'名稱'元素,我想跳過。我只想使用XML :: SAX,因爲我的環境只支持這個模塊。請幫忙。非常感謝。

回答

1

使用棧來記錄哪些節點你內push荷蘭國際集團每次進入一個節點的時間,以及荷蘭國際集團pop每次你離開一個節點:

#!/usr/bin/perl 
use strict; 
use warnings; 
use Data::Dumper; 
use XML::SAX::ParserFactory; 
use XML::SAX::PurePerl; 

my (@nodes, $characters, @names); 

my $factory = new XML::SAX::ParserFactory; 
my $handler = new XML::SAX::PurePerl; 
my $parser = $factory->parser(
        Handler => $handler, 
        Methods => { 
        start_element => sub { 
         push @nodes, shift->{LocalName}; 
        }, 
        characters => sub { 
         $characters = shift->{Data}; 
        }, 
        end_element => sub { 
         if (shift->{LocalName} eq 'name' && $nodes[-2] eq 'company') { 
          push @names, $characters; 
         } 
         pop @nodes; 
        } 
       } 
      ); 
$parser->parse_uri("sample2.xml"); 

print Dumper \@names; 

輸出:

$VAR1 = [ 
      ' abc ', 
      ' xyz ' 
     ]; 

$nodes[-2]是倒數第二個元素@nodes,將解析爲「員工」或「公司」時shift->{LocalName}等於「名」

+0

切換到'XML :: LibXML'或'XML :: Twig'會將代碼減少到大約三行。這正是不適合SAX的工作類型:-) – choroba 2012-01-09 08:54:29

+0

@choroba:假設他的xml文件不是很大,並且內存很受關注,這是真的。在他的問題中,他表示這是他可用的唯一模塊。據我所知,還有一些「XML :: SAX」的使用示例是有限的,所以如果僅僅表明儘可能避免最好的做法是值得的。 ;)我喜歡簡潔的代碼,就像下一個(Perl)的人一樣。 – flesk 2012-01-09 10:15:58