これが私が問題を抱えているいくつかのコードです。私はいくつかのXMLを処理し、OOクラスのメソッドで、ドキュメント内で繰り返されるいくつかのノードのそれぞれから要素を抽出します。各ノードのサブツリーにはそのような要素が1つしかないはずですが、私のコードは、ドキュメント全体で動作しているかのようにすべての要素を取得します。
oine要素を取得することだけを期待していたので、配列の0番目の要素のみを使用します。これにより、関数が間違った値を出力することになります(ドキュメント内のすべての項目で同じです)。
問題を説明するいくつかの簡略化されたコードがあります
$ cat t4.pl
#!/usr/bin/perl
use strict;
use warnings;
use XML::LibXML;
my $xml = <<EndXML;
<Envelope>
<Body>
<Reply>
<List>
<Item>
<Id>8b9a</Id>
<Message>
<Response>
<Identifier>55D</Identifier>
</Response>
</Message>
</Item>
<Item>
<Id>5350</Id>
<Message>
<Response>
<Identifier>56D</Identifier>
</Response>
</Message>
</Item>
</List>
</Reply>
</Body>
</Envelope>
EndXML
my $foo = Foo->new();
my $parser = XML::LibXML->new();
my $doc = $parser->parse_string( $xml );
my @list = $doc->getElementsByTagName( 'Item' );
for my $item ( @list ) {
my $id = get( $item, 'Id' );
my @messages = $item->getElementsByLocalName( 'Message' );
for my $message ( @messages ) {
my @children = $message->getChildNodes();
for my $child ( @children ) {
my $name = $child->nodeName;
if ( $name eq 'Response' ) {
print "child is a Response\n";
$foo->do( $child, $id );
}
elsif ( $name eq 'text' ) {
# ignore whitespace between elements
}
else {
print "child name is '$name'\n";
}
} # child
} # Message
} # Item
# ..............................................
sub get {
my ( $node, $name ) = @_;
my $value = "(Element $name not found)";
my @targets = $node->getElementsByTagName( $name );
if ( @targets ) {
my $target = $targets[0];
$value = $target->textContent;
}
return $value;
}
# ..............................................
package Foo;
sub new {
my $self = {};
bless $self;
return $self;
}
sub do {
my $self = shift;
my ( $node, $id ) = @_;
print '-' x 70, "\n", ' ' x 12, $node->toString( 1 ), "\n", '-' x 70, "\n";
my @identifiers = $node->findnodes( '//Identifier' );
print "do() found ", scalar @identifiers, " Identifiers\n";
print "$id, ", $identifiers[0]->textContent, "\n\n";
}
これが出力です
$ perl t4.pl
child is a Response
----------------------------------------------------------------------
<Response>
<Identifier>55D</Identifier>
</Response>
----------------------------------------------------------------------
do() found 2 Identifiers
8b9a, 55D
child is a Response
----------------------------------------------------------------------
<Response>
<Identifier>56D</Identifier>
</Response>
----------------------------------------------------------------------
do() found 2 Identifiers
5350, 55D
私は期待していました
do() found 1 Identifiers
私は最後の行が
5350, 56D
プラットフォームの問題のため、古いバージョンのXML::LibXMLを使用しています。
Q:問題はそれ以降のバージョンに存在しますか、それとも何か間違ったことをしていますか?