以下工作代码读取包含大量空元素的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
答案 0 :(得分:6)
不幸的是,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声明它。对于互操作性,应该使用empty-element标记,并且只应该对于声明为EMPTY的元素使用。
这意味着声明为EMPTY in a DTD的元素。对于其他元素,或者如果不存在DTD,XML标准建议不要使用自闭标签(“,只应使用”)。但这只是对互操作性的非约束性建议。
答案 1 :(得分:0)
有一个包装变量
$XML::LibXML::setTagCompression
将其设置为true值将强制所有空标签打印为<e></e>
,而false值将强制<e/>
。
请参阅解析器文档中的Restrict sharing options on Drive files。