亲爱的Perl和XML大师
我的任务是使用 XPath 更新 XML 文件中的值。
我在 Perl 中使用XML::LibXML
库来读取,更改和保存XML文件:
# Read XML file
my $parser = XML::LibXML->new();
my $doc = $parser->load_xml(location => $config_file);
my $root = $doc->documentElement();
# Alter nodes\attributes
foreach (keys %environment_values) {
my @nodes = $root->findnodes($_);
if (scalar @nodes < 1) {
print "ERROR: element not found in $config_file by XPath: $_\n";
die;
} elsif (scalar @nodes > 1) {
print "ERROR: more than 1 element (" . scalar @nodes . ") is found in $config_file by XPath: $_\n";
die;
}
my $node = $nodes[0];
if ($node->nodeType == XML_ELEMENT_NODE) {
$node->removeChildNodes();
$node->appendText($environment_values{$_});
} elsif ($node->nodeType == XML_ATTRIBUTE_NODE) {
$node->setValue($environment_values{$_});
} else {
print "ERROR: unknown node type: " . $node->nodeType . "\n";
die;
}
}
# Save the resulting XML file
open (my $fh, '>:raw', $config_file) or die $!;
print $fh $doc->toString();
close $fh;
虽然它生成的文件与原始文件非常相似,但仍有一些麻烦:
<node />
变为<node/>
。有机会解决这些问题吗?我希望获得与原始文件完全相同的XML文件,只有差异是我正在修改的属性值......
P.S。我真的很喜欢NAnt中<xmlpoke>
的简单。但是必须使用Perl进行这项工作。
答案 0 :(得分:3)
我认为换行符的答案可能是你正在使用的模式。
根据http://perldoc.perl.org/PerlIO.html#Defaults-and-how-to-override-them:
如果平台是MS-DOS,并且通常对文本文件执行CRLF到“\ n”翻译,则默认图层为:
unix crlf
(低级“unix”层可以由平台特定的低级别层替换。)
答案 1 :(得分:2)
一般来说,你不会得到你想要的东西 - 例如圆形属性值的单引号和双引号之间的区别以及标记内的空格都将丢失。
最佳可能是使用Perl读取一次并在没有更改的情况下写出,然后运行脚本,并比较这两个文件。