2

XML::LibXML以下のXMLデータを処理するためにCPANモジュールを使用しています。各要素に子要素があるかどうかを判断する必要があります。周りを検索すると、その目的の例は見つかりません。

<A>
    <ts>2012</ts>
    <T>M1</T>
    <T>M2</T>
    <B>
        <id>PC</id>
        <r>10</r>
        <r>30</r>
    </B>
</A>

これは私が書いたPerlコードです

#!/usr/bin/perl

use strict;
use warnings;

use XML::LibXML;

my ($x,$elname,$haschild)= ();
my $parser = XML::LibXML->new();
my $npo    = $parser->parse_file("test.xml");
my $rootel = $npo -> getDocumentElement();
$elname = $rootel -> nodeName();
print "Root name=$elname\n";

foreach $x ($rootel->childNodes) {
    $elname = $x -> nodeName();
    $haschild = $x->hasChildNodes;
    print "Child name = $elname and has child = $haschild.\n" unless ($elname =~ /#text/i);
}

以前childNodesは各ノードを調べていましたが、ノードに子があるかどうかを判断する簡単な方法が見つかりません。

次のようなすべてのノードをループした後、結果が得られることを期待しています。

A: Has children
ts: Has none
T: has none
T: has none
B: Has children
id: Has none
r: Has none
r: Has none

私が得ている結果は次のようになります:

Root name=A
Child name = ts and has child = 1.
Child name = T and has child = 1.
Child name = T and has child = 1.
Child name = B and has child = 1.

hasChildNodes条件チェック後、すべてのノードがtrueを返すようです。

4

3 に答える 3

5

あなたが求めているのは、ノードの子要素の数です。ノードには、テキストと意味のない空白が含まれます。

ノードが持つ子要素の数をカウントする最も簡単な方法はfindnodes('*')->size、XPath 式が子*要素のみをカウントするように使用することです。

ここに、あなたが説明したことを行うコードがあります

use v5.14;
use warnings;

use XML::LibXML;

my $xml = XML::LibXML->load_xml(string => <<XML);
<A>
    <ts>2012</ts>
    <T>M1</T>
    <T>M2</T>
    <B>
        <id>PC</id>
        <r>10</r>
        <r>30</r>
    </B>
</A>
XML

my $nodes = $xml->findnodes('//*');
foreach my $node ($nodes->get_nodelist) {
  my $children;
  for ($node->findnodes('*')->size) {
    $children = 'none' when 0;
    $children = '1 child' when 1;
    default { $children = "$_ children" }
  }
  printf "%s: has %s\n", $node->localname, $children;
}

出力

A: has 4 children
ts: has none
T: has none
T: has none
B: has 3 children
id: has none
r: has none
r: has none
于 2012-05-28T22:12:53.820 に答える
3

hasChildNodesメソッドはどうですか?

use XML::LibXML;
my $xml = XML::LibXML->createDocument;
$xml->setDocumentElement($xml->createElement('root'));
$xml->documentElement->addChild($xml->createElement('son'));
for my $node ($xml->documentElement,
              $xml->documentElement->firstChild) {
    print $node->hasChildNodes, "\n";
}

版画

1
0

テキスト ノードも子ノードであることに注意してください (つまり、ノードと要素は異なる概念です)。

于 2012-05-28T22:01:14.630 に答える
1

If you just need to know if a child node exists then the test:

$node->exists('*')

would be more efficient than:

$node->findnodes('*')->size

because it would exit as soon as the first node had been found.

于 2015-03-06T11:21:39.767 に答える