2016-12-19 10 views
2

Я создаю XML, чтобы перейти к API и API возвращает это (данные сбрасывали):В perl как мне пройти через эту структуру?

(
    "Data::Dump", 
    { 
     SiteDevices => { 
     "device" => { 
         1102 => { address => "1.2.3.4", riskfactor => "1.0", riskscore => "0.0" }, 
         1136 => { address => "1.2.3.5", riskfactor => "1.0", riskscore => "0.0" }, 
         20491 => { address => "1.2.3.6", riskfactor => "1.0", riskscore => "0.0" }, 
         129644 => { address => "1.2.3.7", riskfactor => "1.0", riskscore => "0.0" }, 
         129645 => { address => "1.2.3.8", riskfactor => "1.0", riskscore => "0.0" }, 
         130408 => { address => "1.2.3.9", riskfactor => "1.0", riskscore => "0.0" }, 
         135975 => { address => "1.2.3.10", riskfactor => "1.0", riskscore => "0.0" }, 
         137642 => { address => "1.2.3.11", riskfactor => "1.0", riskscore => "0.0" }, 
        }, 
     "site-id" => 27, 
     }, 
     success => 1, 
    }, 
) 

я хочу Переберите и печатать устройства и IP-адреса, связанные с ними, и я для жизни меня не может придумать какой-либо код для этого. Какого черта я пропал ?! Я попытался пройти через хэш, хеш хешей и т. Д. Не могу заставить его работать. Если у кого-то из вас есть секунда и вы можете дать ответ, я могу пожать головой в позоре, что было бы потрясающе.

Я попытался:

foreach my $key (keys %{ $output->{‘SiteDevices’}->{‘device’} }) { 
     print $key 
     print $key->{‘address’} 
} 

и

foreach my $key (keys %{ $output{‘SiteDevices’}{‘device’} }) { 
     print $key 
     print $key{‘address’} 
} 

но ни работы.

+0

Сколько записей 'SiteDevices' находится в выводе? Только один? – stevieb

+0

Это выглядит подозрительно, как разбор XML. Это случайно?Если это так, я бы посоветовал вам лучше работать с потоком вверх и использовать лучший парсер. Добавьте пример XML, и вам будет намного проще дать вам лучший пример. – Sobrique

ответ

5

Вы упоминаете это разборе XML. Похоже, что вы разобрана его с XML::Simple и that's just not a good idea.

Почему не вместо:

#!/usr/bin/env perl 
use strict; 
use warnings; 

use XML::Twig; 

## get xml somehow here. parsefile if it's a file already. 
my $twig = XML::Twig -> new -> parse ($your_xml); 

foreach my $device ($twig -> get_xpath('//devices')) { 
    print $device -> att('name'), " => "; 
    print $device -> att('address'),"\n"; 
} 

полезная вещь здесь xpath - это не регулярное выражение, но это своего рода похожи - и это относится к XML. В этом случае //device говорит: «Найдите узел <device> в любом месте дерева. (И затем мы извлекаем атрибуты).

Это может работать для вашего сценария, но вы можете быть более конкретным, указав более длинный путь:

  • ./device - непосредственно ниже текущего узла.
  • .//device - в любом месте ниже текущего узла.
  • /root/SiteDevices/device - узлы, соответствующие этому «дереву».

Вы также можете использовать xpath для поиска по атрибутам:

  • .//device[@name="1136"] найдет что-то с соответствующим значением и атрибута.

См. XML Twig Краткая справочная информация о некоторых руководствах о том, как это сделать.

+1

Я хочу поблагодарить вас за это! Я бил головой о стол на пару дней, пытаясь понять это. И вы исправили его в считанные секунды. Я собираюсь прочитать немного больше о том, как работает твист, потому что я сделал свалку, и у него сумасшедшая информация. Но цикл печатает необходимую информацию !!! – robamcclellan

+1

@robamcclellan: Обратите внимание, что Sobrique использовал XPath '// devices', который находит все узлы' devices' в любом месте документа. Думаю, он выбрал это, потому что мы не видели ваши данные XML и поэтому не знаем названия корневого элемента. Обычно было бы лучше использовать что-то вроде '/ root/SiteDevices/device', чтобы изолировать узлы более конкретно, но мы не можем сказать, что такое' root'. – Borodin

+1

@robamcclellan вы, вероятно, не хотите выгружать объект XML :: Twig (или любой объект XML :: Twig :: Elt). Подумайте об этом как о колбасе; -) Вы можете использовать метод '_dump' для получения древовидного представления, но на самом деле довольно печатная XML-информация будет столь же информативной. Посмотрите на http://xmltwig.org/xmltwig/quick_ref.html первый список полезных методов – mirod

2

Я считаю, что следующий цикл сделает то, что вы пытаетесь выполнить. Он извлекает каждое устройство из дерева, затем извлекает из его адрес, и печатает как:

for my $device (keys %{ $output->{SiteDevices}{device} }){ 
    print "$device: $output->{SiteDevices}{device}{$device}{address}\n"; 
} 

В своих тестах, вы пытаетесь использовать имя ключа в качестве хэш/ссылки на хэш, который не будет работать , Вам нужно вернуть извлеченный ключ в хеш для выполнения дополнительных выделений.

выход, на основе одной записи я извлеченной из Вашего вопроса:

129644: 1.2.3.7 
129645: 1.2.3.8 
130408: 1.2.3.9 
137642: 1.2.3.11 
1136: 1.2.3.5 
135975: 1.2.3.10 
1102: 1.2.3.4 
20491: 1.2.3.6 

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

  • Нет связанных вопросов^_^