在我设置一个原始包含一些数据值的节点后,我希望此节点的空/空文本值为缩写形式:
带文字:
<frog>green</frog>
缩写形式:
<frog/>
当前代码:
foreach my $child ($node->getChildnodes())
{
if ($child->nodeType == XML_TEXT_NODE)
{
my $data = $child->getData();
$data =~ s/(?$case_flag)$sv/$rv/g;
$child->setData ($data);
#my $xyz = $parser->parse_balanced_chunk ($node->toString(0))->toString(0);
}
}
注释掉的行会返回我想要的内容,但我无法使用缩写标记将其恢复到文档中。
答案 0 :(得分:2)
缩写标签(例如<frog/>
)是除了属性之外没有子节点的元素的一种可能表示。它完全等同于其未缩写的形式(<frog></frog>
)。就像你想要的那样,XML :: LibXML会尽可能使用缩写形式。
$ perl -MXML::LibXML -e'
my $doc = XML::LibXML->new()->parse_string("<root><foo></foo></root>");
print $doc->toString();
'
<?xml version="1.0"?>
<root><foo/></root>
&#34;尽可能&#34;表示当元素除了属性之外没有子元素时,意味着$node->childNodes()
什么都不返回。
但在您的情况下,元素仍然有一个子节点:一个文本节点,其值为空字符串。这可以防止XML :: LibXML缩写元素。如果您希望XML :: LibXML缩写元素,那么如果它是空的,则由您来删除它。修正:
for my $child ($node->getChildnodes()) {
if ($child->nodeType == XML_TEXT_NODE) {
my $data = $child->getData();
$data =~ s/(?$case_flag)$sv/$rv/g;
if ($data eq "") {
$node->removeChild($child);
} else {
$child->setData($data);
}
}
}
以下是我用于测试的代码。
你现在在做什么:
$ perl -MXML::LibXML -e'
my $doc = XML::LibXML->new()->parse_string("<root><foo> </foo></root>");
for my $node ($doc->findnodes("//foo")) {
$_->setData("") for $node->childNodes();
}
print $doc->toString();
'
<?xml version="1.0"?>
<root><foo></foo></root>
修复:
$ perl -MXML::LibXML -e'
my $doc = XML::LibXML->new()->parse_string("<root><foo> </foo></root>");
for my $node ($doc->findnodes("//foo")) {
$node->removeChild($_) for $node->childNodes();
}
print $doc->toString();
'
<?xml version="1.0"?>
<root><foo/></root>
答案 1 :(得分:1)
缩写标签(例如<frog/>
)是除了属性之外没有子节点的元素的一种可能表示。它完全等同于其未缩写的形式(<frog></frog>
)。您可以通过传递给构造函数的选项控制一些解析器的输出 - 例如您可以告诉解析器通过'no_blanks'选项删除空节点 - 但是没有选项可以使XML :: LibXML尽可能输出缩写标签。
您可以做的是在序列化XML文档后应用正则表达式:
xyz =~ s{<\s*([^>]+)\s*>\s*</\s*\1\s*>}{<$1/>}g;