我有一个问题,我希望有人可以提供帮助...
我有以下示例xml结构:
<library>
<book>
<title>Perl Best Practices</title>
<author>Damian Conway</author>
<isbn>0596001738</isbn>
<pages>542</pages>
<image src="http://www.oreilly.com/catalog/covers/perlbp.s.gif"
width="145" height="190" />
</book>
<book>
<title>Perl Cookbook, Second Edition</title>
<author>Tom Christiansen</author>
<author>Nathan Torkington</author>
<isbn>0596003137</isbn>
<pages>964</pages>
<image src="http://www.oreilly.com/catalog/covers/perlckbk2.s.gif"
width="145" height="190" />
</book>
<book>
<title>Guitar for Dummies</title>
<author>Mark Phillips</author>
<author>John Chappell</author>
<isbn>076455106X</isbn>
<pages>392</pages>
<image src="http://media.wiley.com/product_data/coverImage/6X/0750/0766X.jpg"
width="100" height="125" />
</book>
</library>
我认为应该有效的代码:
use warnings;
use strict;
use XML::LibXML;
my $parser = XML::LibXML->new();
my $xmldoc = $parser->parse_file('/path/to/xmlfile.xml');
my $width = "145";
my $query = "//book/image[\@width/text() = '$width']/author/text()";
foreach my $data ($xmldoc->findnodes($query)) {
print "Results: $data\n";
}
预期输出:
达米安康威 汤姆克里斯蒂安森但我没有得到任何回报。
我认为这会匹配“book”元素中任何“author”元素的文本内容,该元素还包含一个“image”元素,其属性“width”的值为145.
我确信我忽视了一些非常明显的事情,但无法弄清楚我做错了什么。
非常感谢您的帮助
答案 0 :(得分:4)
你快到了。请注意,author
不是image
的孩子。属性没有text()子元素,您可以直接将它们的值与字符串进行比较。此外,需要toString
来打印值而不是引用。
#!/usr/bin/perl
use warnings;
use strict;
use XML::LibXML;
my $parser = XML::LibXML->new();
my $xmldoc = $parser->parse_file('1.xml');
my $width = "145";
my $query = "//book[image/\@width = '$width']/author/text()";
foreach my $data ($xmldoc->findnodes($query)) {
print "Results: ", $data->toString, "\n";
}
答案 1 :(得分:1)
[在choroba的答案中建立]
如果插入$width
不安全(例如,如果它可能包含'
),您可以使用:
for my $book ($xmldoc->findnodes('/library/book')) {
my $image_width = $book->findvalue('image/@width');
next if !$image_width || $image_width ne '145';
for my $data ($book->findnodes('author/text()')) {
print "Results: ", $data->toString, "\n";
}
}
答案 2 :(得分:0)
XML属性没有文本节点,因此$query
应该是"//book/image[\@width='$width']/author/text()"