3

亲爱的 Perl 和 XML 大师

我的任务是使用XPath更新XML文件中的值。 我使用Perl中的库来读取、更改和保存 XML 文件:
XML::LibXML

# 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;

尽管它生成的文件与原始文件非常相似,但仍然存在一些麻烦:

  1. 换行符(行尾)是 Unix 风格的,虽然原始文件有它们在 Windows 风格。
  2. 关闭 /> 之前的空格被删除,例如<node />变为<node/>.

有机会解决这些问题吗?我希望得到与原始文件完全相同的 XML 文件,唯一的区别是我正在修改的属性值......

PS 我真的很喜欢<xmlpoke>NAnt 的简单性。但是必须使用 Perl 来完成这项工作。

4

2 回答 2

3

我认为换行的答案可能是您正在使用的模式。

根据http://perldoc.perl.org/PerlIO.html#Defaults-and-how-to-override-them

如果平台类似于 MS-DOS 并且通常将 CRLF 转换为“\n”文本文件,则默认层为:

   unix crlf

(低级别的“unix”层可以被平台特定的低级别层替换。)

于 2012-08-31T16:00:46.887 回答
2

一般来说,你不会得到你想要的东西——例如,单引号和双引号轮属性值之间的区别以及标签内的空格将会丢失。

最好的办法是用 Perl 读入一次并写出而不做任何更改,然后运行您的脚本,并比较这两个文件。

于 2012-09-01T04:24:43.580 回答