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

Pet*_*usu 3 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
Run Code Online (Sandbox Code Playgroud)

nwe*_*hof 6

不幸的是,XML::LibXML不支持libxml2的xmlsave模块,它有一个没有空标签的保存标志.

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

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

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

也就是说,片段<foo></foo><foo/>形式都很好,语义相同.任何以不同方式处理此类片段的XML解析器或应用程序都是错误的.


请注意,有些人认为XML规范建议使用自闭标签,但这并不完全正确.XML规范说:

空元素标签可以用于任何没有内容的元素,无论是否使用关键字EMPTY声明它.对于互操作性,应该使用empty-element标记,并且只应该对声明为EMPTY的元素使用.

这意味着在DTD中声明为EMPTY的元素.对于其他元素,或者如果不存在DTD,XML标准建议不要使用自闭标签("只应该使用").但这只是对互操作性的非约束性建议.