我尝试处理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
答案 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::Element和XML::LibXML::Node中都没有记录getAttributes
。您还可以使用attributes
,或将该元素视为哈希引用并要求其键:
my $item = $reader->copyCurrentNode(0);
for my $attr (keys %$item) {
say join '=', $attr, $item->{$attr};
}