Есть ли * простой * способ извлечь глубоко вложенные значения с помощью XML :: Simple?

Я использую XML :: Simple Perl для анализа глубоко вложенного XML и хотел бы извлечь небольшой список элементов примерно на 4 уровня ниже:

A
  B
    C 
      D1
      D2
      D3

В идеале, я хочу сделать это на шаге ввода, если это возможно. Вот так:

my @list = XMLin($xml, { SomeAttribute => 'ButWhat?' });

заканчивая тем же, что и я:

@list = ('D1', 'D2', 'D3')

Возможно ли это? Или просто не так просто?

4 голоса | спросил git-noob 12 FebruaryEurope/MoscowbThu, 12 Feb 2009 14:23:46 +0300000000pmThu, 12 Feb 2009 14:23:46 +030009 2009, 14:23:46

4 ответа


0

Предположим, ваши данные в памяти выглядят так:

my $parsed = {
    A => {
        B => {
            C => [ qw/here is your list/ ],
        },
    },
};

Затем вы можете получить свой список с помощью my @list = @{ $parsed->{A}{B}{C} }.

Это то, что вы пытаетесь сделать?

Изменить: принимая во внимание некоторые комментарии, возможно, вы хотите Data :: Visitor :: Callback . Затем вы можете извлечь все массивы, такие как:

my @arrays;
my $v = Data::Visitor::Callback->new(
    array => sub { push @arrays, $_ },
);
$v->visit( $parsed_xml );

После этого \ @arrays будет список ссылок на произвольно-глубоко вложенные массивы.

Наконец, если у вас просто есть имя атрибута и вы хотите найти сопоставляя узлы XML, вам действительно нужен XPath:

use XML::LibXML;
my $parser = XML::LibXML->new;
my $doc = $parser->parse_string( $xml_string );

# yeah, I am naming the variable data.  so there.
my @data = map { $_->textContent } $doc->findnodes('//p[@id="foo"]');

В любом случае, TMTOWTDI. Если вы работаете с XML, и хотите сделать что-то сложное, XML :: Simple редко является правильным ответом. я использую XML :: LibXML для всего, так как это почти всегда проще.

Еще одна вещь, вы можете захотеть Data :: DPath . Позволяет вы "XPath" структура данных Perl в памяти:

ответил jrockway 12 FebruaryEurope/MoscowbThu, 12 Feb 2009 15:31:06 +0300000000pmThu, 12 Feb 2009 15:31:06 +030009 2009, 15:31:06
0

Опираясь на ответ Джона , вот основной код, который я использую, когда мне нужно делать подобные вещи. Если мне нужно что-то более необычное, я обычно берусь за модуль, если мне позволено это делать.

Трюк в get_values начинается со ссылки верхнего уровня, получает следующий нижний уровень и помещает его в ту же переменную. Это продолжается до тех пор, пока я не достигну того, чего хочу. Большая часть кода - это просто утверждения, гарантирующие, что все работает правильно. В большинстве случаев я нахожу, что это запутанные данные, а не обход (но я делаю много работы по очистке данных). Настройте проверку ошибок в своей ситуации.

используйте карпа qw (квакают);

мой $ parsed = {
  A => {
    B => {
      C => [qw /вот твой список /],
      D => {
        E => [qw /это более глубокий список /],
        },
    },
  },
};

my @keys = qw (A B C D);

my @values ​​= eval {get_values ​​($ parsed, @keys)} или умри;

$ "="] [";
print "Значения [@values] \ n";

sub get_values
    {
    my ($ hash, @keys) = @_;

    мой $ v = $ хэш; # начальная ссылка

    foreach мой ключ $ (@keys)
        {
        croak "Значение не является хешем ref [at $ key!] \ n", если только ref $ v eq ref {};
        croak "Ключ $ key не существует! \ n", если не существует $ v-> {$ key};
        $ v = $ v-> {$ key}; # заменить на ref вниз на один уровень
        }

    croak "Значение не является ссылкой на массив!" разве что ref $ v eq ref [];
    @ $ V;
    }
ответил brian d foy 12 FebruaryEurope/MoscowbThu, 12 Feb 2009 23:09:55 +0300000000pmThu, 12 Feb 2009 23:09:55 +030009 2009, 23:09:55
0

Тот факт, что вы используете XML :: Simple, не имеет значения; вы пытаетесь найти структуру из ссылок и массивов ссылок. Вы знаете, что вы ищете? Всегда ли это будет в одном и том же месте? Если так, то что-то наподобие того, что написал jrockway, поможет легко. Если нет, то вам нужно пройтись по каждой части конструкции, пока не найдете то, что ищете.

Я часто делаю одну вещь: выкидываю структуру, которую возвращает XML :: Simple, используя данные: : Dumper , чтобы посмотреть, как он выглядит (если он всегда будет «выглядеть» одинаково; если нет, то вы можете динамически определить, как его пройти, тестируя что-то - это ссылка и что это за ссылка) , Реальный вопрос: что вы ищете?

ответил Joe Casadonte 12 FebruaryEurope/MoscowbThu, 12 Feb 2009 19:07:19 +0300000000pmThu, 12 Feb 2009 19:07:19 +030009 2009, 19:07:19
0

Data :: Diver предоставляет удобный интерфейс для копания в глубоких структурах.

ответил daotoad 12 FebruaryEurope/MoscowbThu, 12 Feb 2009 20:22:43 +0300000000pmThu, 12 Feb 2009 20:22:43 +030009 2009, 20:22:43

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132