Как я могу использовать XML :: Simple с тегами XML, которые могут иметь один или несколько вложенных элементов? - PullRequest
3 голосов
/ 19 марта 2009

Я задал вопрос вчера Как получить атрибуты тега с помощью XML :: Simple? ссылка, которую я использую для получения XML:

http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=pubmed&id=19273512 (1)

http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=pubmed&id=19291509 (2)

Я добился очень хороших результатов и написал следующий код, который просматривает теги и ищет нужные мне. Я ищу тег 'doi' в 'ArticleIds'

   foreach $item_node (@{$dataSummary->{DocSum}->{Item}})
        {
                if($item_node->{Name} eq 'ArticleIds')
                {
                        foreach $item_node1 (@{$item_node->{Item}})
                        {
                                if ($item_node1->{Name} eq 'doi')
                                {
                                    $doi=  $item_node1->{content};  
                                    last;
                                }
                        }
                        last;

                }
        }

Этот код в основном ищет тег ArticleIds, а затем ищет подтеги под ним, чтобы найти тег 'doi'.

Проблема, с которой я столкнулся, заключается в том, что когда ArticleIds имеет несколько вложенных тегов (как видно из (2)), тогда все работает нормально. Однако, когда тег ArticleIds содержит только ОДИН подтег, как показано в (1), тогда возникают ошибки, и программа просто останавливается.

Я использую Simple Parser и использую дампер, я получил два результата. Вот какая-то часть свалки по ссылке (1)

{ 'Type' => 'List', 'Item' => { 'Type' => 'String', 'content' => '19273512', 'Name' => 'pubmed' }, 'Name' => 'ArticleIds' }

для ссылки (2)

{ 'Type' => 'List', 'Item' => [ { 'Type' => 'String', 'content' => '909564644', 'Name' => 'pii' }, { 'Type' => 'String', 'content' => '10.1080/13506120802676914', 'Name' => 'doi' }, { 'Type' => 'String', 'content' => '19291509', 'Name' => 'pubmed' } ], 'Name' => 'ArticleIds' }

Как видите. когда есть несколько тегов под ArticleIds, то он обрабатывается как массив, следовательно, квадратные скобки.

Что бы кто-нибудь предложил в таком случае?

Ответы [ 3 ]

6 голосов
/ 19 марта 2009

Если файл содержит только один из элементов Item, элемент будет отображаться в хэше. Если есть несколько Item элементов, то он будет отображаться как массив. Вы можете заставить определенные теги всегда содержать список, используя опцию ForceArray. Передайте ему регулярное выражение всех имен атрибутов, которые вы хотите преобразовать в массив, и он позаботится об остальном.

XMLin( 'file.xml', 
       ForceArray => qr{Item}x );

О, также проверьте, какую версию XML :: Simple вы используете. Я думаю, что в более ранних версиях вы могли только указывать ссылку на массив с помощью ForceArray, иначе он не работал вообще. Если он работает только с arrayref, вы можете указать его с помощью:

XMLin( 'file.xml', 
       ForceArray => [ 'Item' ] );

Ознакомьтесь с Документация XML :: Simple CPAN , чтобы увидеть больше возможностей, которые могут вам помочь.

Что касается версии, если вы используете XML :: Simple, который поставляется, например, с дистрибутивом ActiveState, скорее всего, он устарел. Попробуйте взять более новый.

Вы также можете проверить, какой это тип, используя

$item =~ /HASH/  # hash
$item =~ /ARRAY/ # array

или ключевое слово ref (как вы обнаружили)

ref($item) eq 'HASH' 
ref($item) eq 'ARRAY'
4 голосов
/ 19 марта 2009

Я думаю, что одна из проблем, с которыми вы сталкиваетесь, заключается в том, что вы находитесь где-то между XML: Simple не дает вам достаточно ручек и циферблатов, но проблема не достаточно сложна, чтобы вы могли написать что-то более сложное. *

В этом случае я бы достиг что-то вроде XML :: Twig . Он в большей степени основан на событиях, поэтому он может просматривать ваш XML и давать вам контроль, когда вы этого хотите. Получив понравившийся элемент, вы можете делать с ним все, что захотите.

Помимо таких вещей, как Twig, различные вещи, такие как XPath и т. Д., Могут быть также полезны. Они созданы для глубокого изучения XML и извлечения его частей, в отличие от XML :: Simple, который просто дает вам структуру данных.

1 голос
/ 19 марта 2009

У меня была более старая версия XML :: Simple, поэтому я решил использовать функцию ref () и написать несколько дополнительных строк кода.

Спасибо за помощь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...