Синтаксический анализ XML с помощью Perl & XML :: Twig - извлечение дополнительных вложенных потомков - PullRequest
3 голосов
/ 15 сентября 2011

В настоящее время пытаемся выяснить, как лучше всего обрабатывать следующие образцы XML-данных:

<FOO>
    <A>1</A>
    <B>Some Stuff</B>
    <C>
      <C1>
        <C2A><![CDATA[xxx]]></C2A>
        <C2B><![CDATA[yyy]]></C2B>
      </C1>
    </C>
</FOO>

В настоящее время я использую XML :: Twig для работы со всем остальным, и я хотел бы продолжить использовать этот модуль для достижения своих целей, а именно:

извлечь данные из C2A и C2B и назначить их переменным. Обратите внимание, что может быть несколько записей для C2A и C2B, которые необходимо объединить, например, в @array. Однако моя проблема заключается в перемещении дерева вниз, например, если бы мы следовали другому примеру, который я нашел, этого было бы достаточно для этих данных:

<MOVIE_LIST>
    <MOVIE>
        <NAME>Name of the Movie</NAME>
            <MOVIE_ID>28372382</MOVIE_ID>
        <DESCRIPTIONS>
             <LONG_DESCRIPTION>This is a long description</LONG_DESCRIPTION>
             <SHORT_DESCRIPTION>short description</SHORT_DESCRIPTION>
        </DESCRIPTIONS>
        <DIRECTOR_LIST>
            <DIRECTOR>director 1</DIRECTOR>
            <DIRECTOR>director 2</DIRECTOR>
        </DIRECTOR_LIST>
    </MOVIE>
    <MOVIE>
      ...
     </MOVIE>
</MOVIE_LIST>

Решение: @directors = $ elt-> first_child ('DIRECTOR_LIST') -> children_text ('DIRECTOR');

Однако моя проблема в том, что иногда таких детей не существует (например, вообще не отправляются данные из секции C), что не дает мне конца печали, поскольку такие вещи не будут работать: *

@C = $elt->first_child('C')->first_child('C1')->children_text('C2');

Я довольно озадачен тем, как достичь своих целей, и буду благодарен за любые советы, приветствуются упрощенные ответы ;-)

1 Ответ

4 голосов
/ 15 сентября 2011

Если один из методов не находит потомка, он возвращает undef, для которого вы, конечно, не можете вызвать метод.

Таким образом, у вас есть 2 варианта:

Вы можете протестировать каждый шаг вашего цепного выражения:

@C =    $elt->first_child('C') 
     && $elt->first_child('C')->first_child('C1')
     && $elt->first_child('C')->first_child('C1')->children_text('C2')
     || ()
    ;

или использовать XPath:

@C= map { $_->text } $elt->findnodes( './C/C1/C2');

Второй вариант, вероятно, легче читать и поддерживать.

...