Попытка узнать XML::Twig и получить некоторые данные из документа XML.Как пропустить нежелательные элементы с помощью XML :: Twig?
Мой XML содержит 20k + <ADN>
элементов. Элемент Eaach <ADN>
содержит десятки дочерних элементов, один из которых - <GID>
. Я хочу, чтобы процесс только те ADN
где GID
== 1. (См примера XML является __DATA__
)
Документы говорят:
Обработчиков вызываются в установленном порядке, отсортированный по их типу (XPATH сначала выражения, затем регулярные выражения, затем уровень), а затем: указать полный путь (начиная с корневого элемента) или нет, затем по количество шагов в выражении, затем число предикатов, затем количество тестов в предикаты. Обработчики, где последний шаг не указан , указывают шаг (foo/bar/*), запускаемый после других обработчиков XPath. Наконец все обработчики запускаются последним.
Важно: как только обработчик был вызван, если она возвращает 0, то нет другого обработчика не вызывается, кроме всех обработчика, который будет называться в любом случае.
Мой реальный код:
use 5.014;
use warnings;
use XML::Twig;
use Data::Dumper;
my $cat = load_xml_catalog();
say Dumper $cat;
sub load_xml_catalog {
my $hr;
my $current;
my $twig= XML::Twig->new(
twig_roots => {
ADN => sub { # process the <ADN> elements
$_->purge; # and purge when finishes with one
},
},
twig_handlers => {
'ADN/GID' => sub {
return 1 if $_->trimmed_text == 1;
return 0; # skip the other handlers - if the GID != 1
},
'ADN/ID' => sub { #remember the ID as a "key" into the '$hr' for the "current" ADN
$current = $_->trimmed_text;
$hr->{$current}{$_->tag} = $_->trimmed_text;
},
#rules for the wanted data extracting & storing to $hr->{$current}
'ADN/Name' => sub {
$hr->{$current}{$_->tag} = $_->text;
},
},
);
$twig->parse(\*DATA);
return $hr;
}
__DATA__
<ArrayOfADN>
<ADN>
<GID>1</GID>
<ID>1</ID>
<Name>name 1</Name>
</ADN>
<ADN>
<GID>2</GID>
<ID>20</ID>
<Name>should be skipped because GID != 1</Name>
</ADN>
<ADN>
<GID>1</GID>
<ID>1000</ID>
<Name>other name 1000</Name>
</ADN>
</ArrayOfADN>
Он выводит
$VAR1 = {
'1000' => {
'ID' => '1000',
'Name' => 'other name 1000'
},
'1' => {
'Name' => 'name 1',
'ID' => '1'
},
'20' => {
'Name' => 'should be skipped because GID != 1',
'ID' => '20'
}
};
Так,
- Обработчик для
ADN/GID
возвращает0
когда GID = 1. !
- Почему другие обработчики еще вызываются?
- Ожидаемый (желаемый) выход без
'20' => ...
. - Как пропустить нежелательные узлы правильно?
@toolic Согласовывающ документ, _Handlers запускаются в фиксированном order_, так что, вероятно, я не понимаю, как определяется порядок - aka, как решить вышеперечисленное ...;) – cajwine
Проблема в том, что триггер ручного управления в фиксированном порядке _ для определенного элемента_. Они перезагружаются для каждого отдельного. – Sobrique