如何使用XML :: LibXML :: Reader获取属性名称列表?

时间:2019-07-04 15:39:52

标签: xml perl xml-parsing

我尝试处理XML节点,该节点可能在属性中包含许多数据。我想获取属性列表,但不知道如何使用XML::LibXML::Reader实现它?

使用attributeCount可以获取属性的数量,而getAttributeNo可以对属性进行迭代,但这仅是值,而不是属性名称。

我希望看到类似getAttributes的东西,但没有这样的method for attributes

示例代码:

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 个答案:

答案 0 :(得分:3)

这是使用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;
      }
   }
}

答案 1 :(得分:2)

使用节点的浅表副本:

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

XML::LibXML::ElementXML::LibXML::Node中都没有记录getAttributes。您还可以使用attributes,或将该元素视为哈希引用并要求其键:

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