【问题标题】:Using XML::LibXML in Perl to alter XML file: newline chars are Unix, not Windows在 Perl 中使用 XML::LibXML 更改 XML 文件:换行符是 Unix,而不是 Windows
【发布时间】:2012-08-31 15:57:10
【问题描述】:

亲爱的 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;

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

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

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

附:我真的很喜欢 NAnt 中的 &lt;xmlpoke&gt; 多么简单。但必须使用 Perl 来完成这项工作。

【问题讨论】:

  • 兼容的 XML 解析器不得是往返安全的。 (意思是:对于所有有效输入,输入与输出完全相同。) XML 标准中有多个位置要求以破坏性方式修改输入流。在空元素上关闭 /&gt; 之前的空格是必需的或禁止的,但我不知道有多少解析器会记住它以供以后序列化。
  • 谢谢文达祖!有趣的信息...

标签: xml perl newline libxml2 xml-libxml


【解决方案1】:

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

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

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

   unix crlf

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

【讨论】:

  • 感谢您提供非常有用的链接!在我的代码中删除 :raw 有助于处理行尾,似乎 Perl 本身会根据运行的平台来处理它们。
  • @Ivan - 欢迎您。如果答案有用,请随时接受(旁边的复选标记)和/或投票(旁边的向上箭头)。
【解决方案2】:

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

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

【讨论】:

  • 是的,你是对的,解析器读取和写入完整的 XML 内容。所以可能会有不同的表现形式,但是 XML 总是会在写入后验证,这是重点。我想我可以忍受演示文稿的微小变化))
猜你喜欢
  • 2023-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多