Perl XML :: LibXML:如何访问注释节点

Cra*_*igP 5 perl libxml2 xml-libxml

对于我的生活,我无法找到正确的代码来访问我的XML文件中的注释行.难道我用findnodes,find,getElementByTagName(怀疑).

我是否正确地假设这些评论行是可访问的?我希望如此,因为我知道我可以添加评论.

注释节点的类型编号为8,因此它们必须是可解析的.

最终,我想要做的就是删除它们.

my @nodes = $dom->findnodes("//*");

foreach my $node (@nodes) {
  print $node->nodeType, "\n";
}

<TT>
 <A>xyz</A>
 <!-- my comment -->
</TT> 
Run Code Online (Sandbox Code Playgroud)

Bor*_*din 9

  • 如果你需要做的只是删除注释节点的XML副本,那么第一个参数toStringC14N是一个标志,表示你是否想要在输出中注释.省略所有参数隐式地将第一个参数设置为false值,所以

    $doc->toStringC14N
    
    Run Code Online (Sandbox Code Playgroud)

将重现修剪注释的XML.请注意,C14N指定的Canonical XML表单不包含XML声明标头.它总是以UTF-8编码的XML 1.0.

  • 如果在进一步处理之前需要从文档的内存结构中删除注释,那么findnodes使用XPath表达式//comment()将为您找到它们,并将unbindNode它们从XML中删除.

该计划表明

use strict;
use warnings;

use XML::LibXML;

my $doc = XML::LibXML->load_xml(string => <<END_XML);
<TT>
 <A>xyz</A>
 <!-- my comment -->
</TT>
END_XML

# Print everything
print $doc->toString, "\n";

# Print without comments
print $doc->toStringC14N, "\n\n";

# Remove comments and print everything
$_->unbindNode for $doc->findnodes('//comment()');
print $doc->toString;
Run Code Online (Sandbox Code Playgroud)

产量

<?xml version="1.0"?>
<TT>
 <A>xyz</A>
 <!-- my comment -->
</TT>

<TT>
 <A>xyz</A>

</TT>

<?xml version="1.0"?>
<TT>
 <A>xyz</A>

</TT>
Run Code Online (Sandbox Code Playgroud)



更新

要选择特定注释,可以向XPath选择器添加谓词表达式.要在示例数据中查找特定注释,您可以编写

$doc->findnodes('//comment()[. = " my comment "]')
Run Code Online (Sandbox Code Playgroud)

请注意,注释的文本包括除前导和尾部之外的所有内容--,因此空格非常重要,如该调用中所示.

如果你想让事情变得更加松懈,你可以使用normalize=space它来删除前导空格和尾随空格,并将字符串中的每个空白序列合并到一个空格中.现在你可以写了

$doc->findnodes('//comment()[normalize-space(.) = "my comment"]')
Run Code Online (Sandbox Code Playgroud)

即使看起来像这样,同一个电话也会找到你的评论.

<!--
my
comment
-->
Run Code Online (Sandbox Code Playgroud)

最后,您可以使用contains,正如您所期望的那样,只需检查一个字符串是否包含另一个字符串.使用它你可以写

$doc->findnodes('//comment()[contains(., "comm")]')
Run Code Online (Sandbox Code Playgroud)

选择的一个取决于您的要求和您的情况.


ike*_*ami 8

根据XPath规范:

  • *是一个匹配任何名称的元素节点的测试.注释节点不是元素节点.

  • comment() 是一个匹配注释节点的测试.

未经测试:

for $comment_node ($doc->findnodes('//comment()')) {
   $comment_node->parentNode->removeChild($comment_node);
}
Run Code Online (Sandbox Code Playgroud)