Как получить список имен атрибутов с помощью XML :: LibXML :: Reader? - PullRequest
3 голосов
/ 04 июля 2019

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

С помощью attributeCount я могу получить количество атрибутов, а с getAttributeNo перебрать их, но это дает мне только значения, а не имена атрибутов.

Я надеялся увидеть что-то вроде getAttributes, но такого метода для атрибутов не существует

Пример кода:

use strict; use warnings; use 5.010;

use XML::LibXML::Reader;

my $reader = XML::LibXML::Reader->new(IO => \*DATA)
    or die "Cannot read from \\*DATA\n";

while ($reader->read) {
  processNode($reader);
}

sub processNode {
  my $reader = shift;


  if ( $reader->name eq 'item' ) {
    my $count = $reader->attributeCount; 
    say "item has $count attributes";

    for (my $i = 0; $i < $count; $i++) {
      say $reader->getAttributeNo( $i );
    }

    # this would my desired way to access attributes:
    # for my $attr ( $reader->getAttributes ) { 
    #   say "$attr ". $reader->getAttribute( $attr );
    # }
  }
}

__DATA__
<items>
  <item code="PK7000346" name="Lucky" class="MUU" purchaseprice="0.2983" object="UPK" hasvariants="0" ts="2019-06-19T20:04:47"/>
</items>

Желаемый результат - хеш или пары имя / значение, например:

code PK7000346
name Lucky
class MUU
purchaseprice 0.2983
object UPK
hasvariants 0
ts 2019-06-19T20:04:47

Ответы [ 2 ]

3 голосов
/ 04 июля 2019

Вот еще один подход, использующий moveToAttribute:

sub processNode {
  my $reader = shift;

  if ( $reader->name eq 'item' ) {
      my $count = $reader->attributeCount;
      for (my $i = 0; $i < $count; $i++) {
          $reader->moveToAttributeNo( $i );
          say $reader->name, " = ", $reader->value;
      }
   }
}
2 голосов
/ 04 июля 2019

Использовать мелкую копию узла:

if ($reader->name eq 'item'
    && $reader->nodeType == XML_READER_TYPE_ELEMENT
) {
    for my $attr ($reader->copyCurrentNode(0)->getAttributes) {
        say join '=', $attr->name, $attr->value;
    }
}

Кажется, getAttributes не задокументировано ни в XML :: LibXML :: Element , ни XML :: LibXML :: Node . Вы также можете использовать attributes или рассматривать элемент как ссылку на хеш и запрашивать его ключи:

    my $item = $reader->copyCurrentNode(0);
    for my $attr (keys %$item) {
        say join '=', $attr, $item->{$attr};
    }
...