Perl XML::LibXML替换值
我有下面的xml文件,在这里我想写一个perl脚本,这样我可以grep第一本书的名字,然后是作者的名字,如果两者都匹配,将字段“value”从false改为true。例如,如果书名为abc,作者名为john,请将值从false更改为truePerl XML::LibXML替换值,perl,Perl,我有下面的xml文件,在这里我想写一个perl脚本,这样我可以grep第一本书的名字,然后是作者的名字,如果两者都匹配,将字段“value”从false改为true。例如,如果书名为abc,作者名为john,请将值从false更改为true use warnings; use strict; use XML::LibXML; my $parser = XML::LibXML->new(); my $xmldoc = $parser->parse_file('b.xml'); for
use warnings;
use strict;
use XML::LibXML;
my $parser = XML::LibXML->new();
my $xmldoc = $parser->parse_file('b.xml');
for my $book ($xmldoc->findnodes('/library/book')) {
my $name = $book->findvalue('/@name');
if($name eq "abc")
{
print "yes" ;
}
}
我是perl新手,有人能帮我吗?我已经写了一些代码,以达到第一点,检查作者姓名,但这本身是不起作用的
for my $default_author_node ($xmldoc->findnodes(
'/library/book[@name="abc"]/author[@name="john"]/default'
)) {
$default_author_node->setAttribute('value', 'true');
}
但您可能希望名称是可变的
解决方案1:动态构建上述XPath
sub text_to_xpath {
my ($s) = @_;
return qq{"$s"} if $s !~ tr/"//;
return qq{'$s'} if $s !~ tr/'//;
$s = s/"/", '"', "/g;
return qq{concat("$s")};
}
my $target_book_xp = text_to_xpath($target_book);
my $target_author_xp = text_to_xpath($target_author);
for my $default_author_node ($xmldoc->findnodes(
"/library/book[\@name=$target_book_xp]/author[\@name=$target_author_xp]/default"
)) {
$default_author_node->setAttribute('value', 'true');
}
解决方案2:自己做检查
这就是您尝试的,但是XPath/@name
会在文档的根(/
)获取名为name
)的子属性(@
),但其中唯一的节点是根元素(库
)。就像在目录路径中一样,如果要相对于上下文进行搜索,请不要使用前导的/
for my $book_node ($xmldoc->findnodes('/library/book')) {
my $name = $book_node->getAttribute('name');
next if !defined($name) || $name ne $target_book;
for my $author_node ($book_node->findnodes('author')) {
my $name = $book_node->getAttribute('name');
next if !defined($name) || $name ne $target_author;
for my $default_author_node ($author_node->findnodes('default')) {
$default_author_node->setAttribute('value', 'true');
}
}
}
感谢您对解决方案2的帮助,它成功了。我还有一个问题,我想更改同一xml文件中的内容。有办法吗?现在我正在使用print$xmldoc->toString;以及将输出重定向到另一个xml文件。但我不喜欢这样做。没有什么能阻止你保存到同一个文件。还有一个名为
toFile
的方法,它将为您节省一些工作
for my $book_node ($xmldoc->findnodes('/library/book')) {
my $name = $book_node->getAttribute('name');
next if !defined($name) || $name ne $target_book;
for my $author_node ($book_node->findnodes('author')) {
my $name = $book_node->getAttribute('name');
next if !defined($name) || $name ne $target_author;
for my $default_author_node ($author_node->findnodes('default')) {
$default_author_node->setAttribute('value', 'true');
}
}
}