如何使用XML :: LibXML列出XML节点属性?

Ale*_*kin 5 xml perl attr xml-libxml

给出以下XML片段:

<outline>
  <node1 attribute1="value1" attribute2="value2">
    text1
  </node1>
</outline>
Run Code Online (Sandbox Code Playgroud)

我如何获得此输出?

outline
node1=text1
node1 attribute1=value1
node1 attribute2=value2
Run Code Online (Sandbox Code Playgroud)

我已经研究过use XML::LibXML::Reader;,但该模块似乎只提供对其名称引用的属性值的访问.我如何首先获得属性名称列表?

mir*_*rod 5

您可以通过执行找到属性列表 $e->findnodes( "./@*");

下面是一个解决方案,使用纯 XML::LibXML,而不是 XML::LibXML::Reader,适用于您的测试数据。不过它可能对额外的空白和混合内容很敏感,所以在使用它之前先在真实数据上测试它。

#!/usr/bin/perl

use strict;
use warnings;

use XML::LibXML;

my $dom= XML::LibXML->load_xml( IO => \*DATA);
my $e= $dom->findnodes( "//*");

foreach my $e (@$e)
  { print $e->nodeName;

    # text needs to be trimmed or line returns show up in the output
    my $text= $e->textContent;
    $text=~s{^\s*}{};
    $text=~s{\s*$}{};

    if( ! $e->getChildrenByTagName( '*') && $text)
      { print "=$text"; }
    print "\n"; 

    my @attrs= $e->findnodes( "./@*");
    # or, as suggested by Borodin below, $e->attributes

    foreach my $attr (@attrs)
      { print $e->nodeName, " ", $attr->nodeName. "=", $attr->value, "\n"; }
  }
__END__
<outline>
  <node1 attribute1="value1" attribute2="value2">
    text1
  </node1>
</outline>
Run Code Online (Sandbox Code Playgroud)

  • 有更简洁的方法来获取属性。显而易见的是`my @attrs = $e-&gt;attributes`,它返回所有属性节点的列表,但元素节点对象也表现为绑定哈希引用,并且`keys %$e` 将返回所有属性names 而`$e-&gt;{attr_name}` 将返回属性`attr_name` 的值。 (2认同)

Bor*_*din 5

这样的事情可以帮助你.

从您的问题来看,不清楚<outline>数据的根元素是否存在,或者它是否隐藏在更大的文档中.目前还不清楚你想要解决方案的一般性 - 例如,你是否希望以这种方式转储整个文档?

无论如何,这个程序以一种相当简洁的方式从给定的XML输入生成您请求的输出.

use strict;
use warnings;
use 5.014;     #' For /r non-destructive substitution mode

use XML::LibXML;

my $xml = XML::LibXML->load_xml(IO => \*DATA);

my ($node) = $xml->findnodes('//outline');

print $node->nodeName, "\n";

for my $child ($node->getChildrenByTagName('*')) {
  my $name = $child->nodeName;

  printf "%s=%s\n", $name, $child->textContent =~ s/\A\s+|\s+\z//gr;

  for my $attr ($child->attributes) {
    printf "%s %s=%s\n", $name, $attr->getName, $attr->getValue;
  }
}

__DATA__
<outline>
  <node1 attribute1="value1" attribute2="value2">
    text1
  </node1>
</outline>
Run Code Online (Sandbox Code Playgroud)

产量

outline
node1=text1
node1 attribute1=value1
node1 attribute2=value2
Run Code Online (Sandbox Code Playgroud)