- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
这是一些我遇到问题的代码,我处理了一些 XML,并在 OO 类的方法中从文档中重复的几个节点中的每一个节点中提取了一个元素。每个节点的子树中应该只有一个这样的元素,但我的代码获取所有元素,就好像它在整个文档上操作一样。
因为我只希望得到 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。
问:是后续版本有问题还是我操作有误?
最佳答案
//para selects all the para descendants of the document root
(强调我自己)。所以你的电话
$node->findnodes( '//Identifier' )
正在忽略上下文节点 $node
并在文档中的任何位置搜索所有 Identifier
元素
要获取上下文节点的所有 Identifier
后代,您必须添加一个点,如下所示
$node->findnodes('.//Identifier');
但由于 $node
始终是 Response
元素,而 Identifier
是 Response
的直接子元素,您可以随便写
$node->findnodes('Identifier');
您写这篇文章似乎有点忙不过来了。我知道您已将代码缩减为示例,但您真的需要单独的包吗?明智地应用 XPath 可以做很多事情。
最明显的变化是您无需遍历所有 个子项 - 您可以简单地挑选出您感兴趣的子项。
这段重构代码可能值得一读
use strict;
use warnings;
use XML::LibXML;
my $parser = XML::LibXML->new;
my $doc = $parser->parse_fh(*DATA);
for my $item ( $doc->findnodes('//Item') ) {
print "\n";
my ($id) = $item->findvalue('Id');
printf "Item Id: %s\n", $item->findvalue('Id');
my @messages = $item->findnodes('Message');
for my $message (@messages) {
my ($response) = $message->findnodes('Response');
printf "Response Identifier: %s\n", $response->findvalue('Identifier');
}
}
__DATA__
<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>
输出
Item Id: 8b9a
Response Identifier: 55D
Item Id: 5350
Response Identifier: 56D
关于xml - Perl XML::LibXML $node->findnodes($xpath) 找到它不应该找到的节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11955052/
我创建了一个根据 MySQL 行生成 XML 的 WebService,结果如下: 1 12345 12345 12345
我有一个包含 1,2,...,9 在内的整数的二叉搜索树。我的遍历方法有效,我知道节点在那里并且顺序正确。 我创建了两种搜索方法,一种查找并返回节点,另一种调用该方法并根据返回的内容打印节点是否存在(
这是我的代码的一个简短示例,但很好理解我的问题。 我有一个像这样的 xml 文件: one two 这是我在delphi中的代码: procedure TForm1.But
我有以下 xml 代码片段: textb textc textd textb textc textd 我用 xml::twig解析如下: my
我有一个 TreeView 控件。下面的代码用于查找具体的父节点。 TreeView AllProductsTreeView; TreeNode nodeFound = AllProductsTree
XML: Gigi Male 3 Gigia Female 2
我正在使用 HTML-TreeBuilder-XPath 解析html内容 在Perl中。我已经得到了我需要的数据的xpath位置。我面临的问题是,单个结果返回了xpath $html->findno
我有一个简单的 xml 文件,如下所示: Bactrian Camel 450 to 500 kg. Blah blah blah
我有一个实现可迭代接口(interface)的 LinkedList 类,在 LinkedList 类中我有一个内部节点类。我有另一个运行 JUnit 4 的 TestLinkedList 类。该测试
我是 XML 新手,正在尝试使用 Delphi XE TXMLDocument 访问以下 XML 中的数据 4294967295 18 123.6
我正在使用 XML::LibXML::Reader 解析大型文档,遇到了属性 xmlns 导致 findnodes() 失败的问题。我通过添加正则表达式来删除 xmls 属性来修复它,但我想知道是否有
我有一个多线程程序,它使用 QMap 来存储一些数据,但是当调用 contains() 函数时,它时不时地在同一行崩溃: myMap.contains(a) -> 键和值不是指针。 崩溃: #0 fi
我正在使用 XML::LibXML::Reader 解析大型文档,遇到了属性 xmlns 导致 findnodes() 失败的问题。我通过添加正则表达式来删除 xmls 属性来修复它,但我想知道是否有
我正在尝试实现 findNode 方法作为 java 中二叉搜索树的一部分。 public Node findNode(int findkey){ Node tempNode5 = root;
xml: Gigi Male 3 ../images/Gigi.png Gigia
这是一些我遇到问题的代码,我处理了一些 XML,并在 OO 类的方法中从文档中重复的几个节点中的每一个节点中提取了一个元素。每个节点的子树中应该只有一个这样的元素,但我的代码获取所有元素,就好像它在整
我正在使用 XML::LibXML ,我只需要获取 XPath 表达式指定的节点数。 使用下面的前两个代码行中的任何一个都会产生我正在寻找的内容。我可以使用 count XPath 函数与 findv
谁能解释为什么 ChildNodes.FindNode('') (1) 失败但 ChildNodes[''] (2) 成功? ==> 代码: const cNodeSOAPEnvelope =
以下只是我正在处理的 XML 的一小部分。我想提取子树下的所有属性、标签名称和文本。 Chicago 30.970 -90.723 我有这样的编码示例: #!/usr/bin/perl u
我是一名优秀的程序员,十分优秀!