5

私の人生では、XML ファイルのコメント行にアクセスするための適切なコードがわかりません。findnodes, find,を使用しますgetElementByTagNameか (疑います)。

これらのコメント行にアクセスできるという正しい仮定をしていますか? コメントを追加できることがわかっているので、そう願っています。

コメント ノードのタイプ番号は 8 であるため、解析可能である必要があります。

最終的に、私がやりたいことはそれらを削除することです。

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

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

<TT>
 <A>xyz</A>
 <!-- my comment -->
</TT> 
4

3 に答える 3

9
  • コメント ノードを削除した XML のコピーを作成するだけでよい場合、 の最初のパラメーターはtoStringC14N、出力にコメントが必要かどうかを示すフラグです。すべてのパラメーターを省略すると、最初のパラメーターが暗黙的に false 値に設定されるため、

    $doc->toStringC14N
    

コメントをトリミングした 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;

出力

<?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>



アップデート

特定のコメントを選択するには、述語式を XPath セレクターに追加します。サンプルデータで特定のコメントを見つけるには、次のように書くことができます

$doc->findnodes('//comment()[. = " my comment "]')

コメントのテキストには、先頭と末尾の を除くすべてが含まれていることに注意--してください。そのため、その呼び出しに示されているように、スペースは重要です。

物事をもう少し緩くしたい場合はnormalize=space、 を使用できます。これは、先頭と末尾の空白を削除し、文字列内の空白のすべてのシーケンスを 1 つのスペースに短縮します。今、あなたは書くことができます

$doc->findnodes('//comment()[normalize-space(.) = "my comment"]')

そして、このように見えても、同じ呼び出しでコメントを見つけることができます。

<!--
my
comment
-->

最後に、 を利用できます。これは、ご想像のとおり、ある文字列に別の文字列が含まれているcontainsかどうかを単純にチェックします。それを使って書くことができます

$doc->findnodes('//comment()[contains(., "comm")]')

どちらを選択するかは、要件と状況によって異なります。

于 2013-10-17T17:10:18.293 に答える
8

XPath仕様によると:

  • *任意の名前の要素ノードに一致するテストです。コメント ノードは要素ノードではありません。

  • comment()コメント ノードに一致するテストです。

未テスト:

for $comment_node ($doc->findnodes('//comment()')) {
   $comment_node->parentNode->removeChild($comment_node);
}
于 2013-10-17T17:01:13.090 に答える