простой вопрос XML для Perl - как получить конкретные элементы - PullRequest
0 голосов
/ 10 января 2011

Я пытаюсь понять, как пройтись по XML, но я много читал и все еще застреваю.Вот информация:

Я использую API Wordnik для извлечения XML с XML :: Simple:

 $content = get($url);
 $r = $xml->XMLin("$content");

Фактический XML выглядит следующим образом:

<definitions>
−
<definition sequence="0" id="0">
−
<text>
To withdraw one's support or help from, especially in spite of duty, allegiance, or responsibility; desert:  abandon a friend in trouble. 
</text>
<headword>abandon</headword>
<partOfSpeech>verb-transitive</partOfSpeech>
</definition>
−
<definition sequence="1" id="0">
−
<text>
To give up by leaving or ceasing to operate or inhabit, especially as a result of danger or other impending threat:  abandoned the ship. 
</text>
<headword>abandon</headword>
<partOfSpeech>verb-transitive</partOfSpeech>
</definition>
−
<definition sequence="2" id="0">
−
<text>
To surrender one's claim to, right to, or interest in; give up entirely. See Synonyms at relinquish.
</text>
<headword>abandon</headword>
<partOfSpeech>verb-transitive</partOfSpeech>
</definition>
−
<definition sequence="3" id="0">

...

То, что я хочу, это просто ПЕРВАЯ часть определения.Я использую этот код, но он получает ПОСЛАНИЕ ПОСЛЕДНЕГО определения:

    if($r->{definition}->{0}->{partOfSpeech}) {
      $pos = $r->{definition}->{0}->{partOfSpeech};
     }
else { $pos = $r->{definition}->{partOfSpeech}; }

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

 while (my ($k, $v) = each %{$r->{definitions}->{definition}[0]->{sequence}->{partOfSpeech}}) {
  $v =~ s/'/'"'"'/g;
  $v = "'$v'";
  print "export $k=$v\n";
 }

Наконец, когда я делаю «print Dumper ($ r)», он дает мне следующее:

$VAR1 = {
          'definition' => {
                          '0' => {
                                 'partOfSpeech' => 'noun',
                                 'sequence' => '6',
                                 'text' => 'A complete surrender of inhibitions.',
                                 'headword' => 'abandon'
                               }
                        }
        };

(И это «существительное», которое вы видите, является последним (6-м) элементом определения / partofspeech).


Исходя из ответа RC ниже, мой новый код выглядит следующим образом:

$content = get($url);
$r = $xml->XMLin("$content", KeyAttr => { definition => 'sequence'});
while (my ($k, $v) = each %{$r->{definition}}) {
    $v=$r->{definition}->{$k}->{partOfSpeech};
    print "export $k=$v\n";
}

Это распечатывает следующее:

export 6='noun'
export 4='verb-transitive'
export 1='verb-transitive'
export 3='verb-transitive'
export 0='verb-transitive'
export 2='verb-transitive'
export 5='noun'

Так что это хорошо, и он экспортирует правильные пары.Но теперь проблема в том, что порядок выключен (что, скорее всего, является проблемой Wordnik, а не проблемой программирования).Как мне отсортировать это по ключу?Как то так?

sort($r->{definition});

Ответы [ 3 ]

3 голосов
/ 10 января 2011

Можно также использовать XML :: Twig , чтобы просмотреть файл для вас и помочь в извлечении данных:

use XML::Twig;

my $content = do { local $/; <DATA> };      # get data

XML::Twig->new(twig_handlers => {
    definition => sub {
        warn "---\n",
            "sequence = ",     $_->att('sequence'), "\n",
            "text = ",         $_->first_child_trimmed_text('text'), "\n",
            "headword = ",     $_->first_child_trimmed_text('headword'), "\n",
            "partOfSpeech = ", $_->first_child_trimmed_text('partOfSpeech'), "\n";
        $_->purge;
    },
})->parsestring($content);

Это также более эффективно, поскольку не требуется загружать всю структуру в память (метод purge очищает обработанные данные для вас).

3 голосов
/ 10 января 2011

Из XML :: Простой Документ:

Примечание 1: значение по умолчанию для KeyAttr - это ['name', 'key', 'id']. Если Вы не хотите складывать на входе или разворачиваясь на выходе вы должны установить эта опция в пустой список отключить функцию.

Я думаю, добавление KeyAttr => { definition => 'sequence' } к XMLin опциям может решить вашу проблему.

0 голосов
/ 15 февраля 2011

Вы можете попробовать WWW :: Wordnik :: API (я автор.)

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