我正在使用 perl XML::LibXML 模块来操作 XML 文件。
我想删除 XML 节点的开始和结束标记(如果它具有某个属性),使其文本和子节点成为该节点父节点的一部分。
这是一次不成功的尝试。如果失败并显示
insertBefore/insertAfter: HIERARCHY_REQUEST_ERR
:
#!/usr/bin/env perl
use 5.020;
use warnings;
use XML::LibXML;
#the input xml
my $inputstr = <<XML;
<root>
<a>
<b class="deletethistag">keep this text<c>keep this c node</c>keep this text too</b>
<b class="someothertag">don't change this</b>
<b>don't change this node without an attribute</b>
<c class="type1">don't change this either</c>
</a>
</root>
XML
my $desiredstr = <<XML ;
<root>
<a>keep this text<c>keep this c node</c>keep this text too
<b class="someothertag">don't change this</b>
<b>don't change this node without an attribute</b>
<c class="type1">don't change this either</c>
</a>
</root>
XML
my $dom = XML::LibXML->load_xml(
string => $inputstr
);
# Convert $inputstr to $desiredstr *** doesn't work ***
foreach my $node ($dom->findnodes(q#//a/b[@class="deletethistag"]/*#)) {
my $nodestring = $node->toString(1);
say STDERR $nodestring;
my $replacementnode = XML::LibXML->load_xml(string => $nodestring);
$node->parentNode()->insertAfter($replacementnode, $node);
$node->unbindNode();
}
say $dom->toString(1);
我想使用代码从文件中删除
<span lang="en" xml:space="preserve">...</span>
标记,但我已将其作为一个更一般的问题,以便我了解更多使用 XML::LibXML 的细节。
$node->childNodes()
返回 $node 的所有文本节点和其他子节点。
将 $node 的所有子节点插入到 $node 的父节点中与 $node 相同的位置。然后用
$node->unbindNode()
删除原来的$node
这是一个工作脚本:
#!/usr/bin/env perl
use 5.020;
use warnings;
use XML::LibXML;
#the input xml
my $inputstr = <<XML;
<root>
<a>
<b class="deletethistag">keep this text<c>keep this c node</c>keep this text too</b>
<b class="someothertag">don't change this</b>
<b>don't change this node without an attribute</b>
<c class="type1">don't change this either</c>
</a>
</root>
XML
my $desiredstr = <<XML ;
<root>
<a>
keep this text<c>keep this c node</c>keep this text too
<b class="someothertag">don't change this</b>
<b>don't change this node without an attribute</b>
<c class="type1">don't change this either</c>
</a>
</root>
XML
my $dom = XML::LibXML->load_xml(
string => $inputstr
);
for my $node ($dom->findnodes(q#//a/b[@class="deletethistag"]#)) {
my $parent = $node->parentNode();
for my $child_node ( $node->childNodes() ) {
$parent->insertBefore($child_node, $node);
}
$node->unbindNode();
}
say $dom->toString();