perl - 如何防止 XML::LibXML 使用自闭标记保存修改后的 xml

标签 perl xml-libxml

以下工作代码读取我的 XML包含大量空元素的文件,然后应用 2 个更改并以不同的名称再次保存。 但它也会更改空元素,如 <element></element>自动关闭标签,如 <element />这是不需要的。
如何不使用自闭合标签保存? 或者换句话说如何分辨XML::LibXML使用空标签? 原始文件是在商业应用程序中生成的,它使用带有空元素的样式,所以我想支持它。

#! /usr/bin/perl

use strict;
use warnings;
use XML::LibXML;

my $filename = 'out.xml';
my $dom = XML::LibXML->load_xml(location => $filename);
my $query = '//scalar[contains(@name, "partitionsNo")]/value';
for my $i ($dom->findnodes($query)) {
$i->removeChildNodes();
$i->appendText('16');
}

open my $out, '>', 'out2.xml';
binmode $out;
$dom->toFH($out);
# now out2.xml has only self-closing tags where previously 
# were used empty elements

最佳答案

不幸的是,XML::LibXML不支持 libxml2 的 xmlsave具有 flag 的模块在没有空标签的情况下保存。

作为解决方法,您可以向空元素添加一个空文本节点:

for my $node ($doc->findnodes('//*[not(node())]')) {
    # Note that appendText doesn't work.
    $node->appendChild($doc->createTextNode(''));
}

这对于大型文档来说有点昂贵,但我不知道有更好的解决方案。

也就是说,碎片 <foo></foo><foo/>都是格式良好并且语义等价。任何以不同方式处理此类片段的 XML 解析器或应用程序都是错误的。


请注意,有些人认为 XML 规范建议使用自闭合标记,但事实并非如此。 XML 规范说:

Empty-element tags may be used for any element which has no content, whether or not it is declared using the keyword EMPTY. For interoperability, the empty-element tag should be used, and should only be used, for elements which are declared EMPTY.

这意味着声明为 EMPTY in a DTD 的元素.对于其他元素,或者如果不存在 DTD,XML 标准建议不要使用自闭合标记(“并且只应使用”)。但这只是互操作性的非约束性建议。

关于perl - 如何防止 XML::LibXML 使用自闭标记保存修改后的 xml,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45691203/

相关文章:

regex - 使用 MARPA::R2 perl 解析双引号字符串

c# - 删除大文本文件中的所有重复项

linux - 在 Perl 中添加默认系统换行符

xml - Perl 5.8.8 不支持 XML::LibXML 吗?

xml - 使用 perl + LibXML 将 XSLT 样式表声明添加到给定的 XML

apache - Perl 库无法在 WampServer 上运行

regex - 在 cmdshell 中解析 fcinfo 输出

c - RaiseError (PERL, DBI) 相当于 unixODBC C API?

xml - 如何使用 perl/LibXML 在 DOCTYPE 中创建 ENTITY 引用