2012-01-09 2 views
1

Как обрабатывать имена повторяющихся элементов в perl XML :: SAX module? Ниже мой 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-> employee-> компания-> имя? (Я должен иметь возможность печатать «abc» и «xyz»). Причина, по которой я спрашиваю об этом, состоит в том, что на employee-> employee-> name, который я хочу пропустить, есть еще один элемент «name». Я хотел бы использовать 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

+0

@choroba: Это правда, если его xml-файл не огромен, а память вызывает беспокойство. В своем вопросе он утверждает, что это единственный доступный ему модуль. Насколько я могу судить, есть также ограниченные примеры использования XML: SAX, поэтому стоит того, чтобы показать, что лучше всего избегать, если это возможно. ;) Я обожаю краткий код так же, как и следующий (Perl) парень. – flesk

Смежные вопросы