首页 > 解决方案 > Perl 删除重复的 XML 标签

问题描述

我有以下 XML 文件:

<d:entry id="a" d:title="a">
  <d:index d:value="a" d:title="a"/>
  <d:index d:value="b" d:title="b"/>
  <d:index d:value="a" d:title="a"/>
  <d:index d:value="c" d:title="c"/>
  <d:index d:value="b" d:title="b"/>
  <d:index d:value="a" d:title="a"/>
  <d:index d:value="b" d:title="b"/>
  <div>This is the content for entry.</div>
</d:entry>
<d:entry id="b" d:title="b">
  <d:index d:value="a" d:title="a"/>
  <d:index d:value="b" d:title="b"/>
  <div>This is the content for entry.</div>
</d:entry>

(为了可读性添加了空格。)

有一些重复<d:index,我需要去掉所有重复,只保留一个唯一的<d:index。想要的效果是这样的:

<d:entry id="a" d:title="a">
   <d:index d:value="a" d:title="a"/>
   <d:index d:value="b" d:title="b"/>
   <d:index d:value="c" d:title="c"/>
   <div>This is the content for entry.</div>
</d:entry>
<d:entry id="b" d:title="b">
  <d:index d:value="a" d:title="a"/>
  <d:index d:value="b" d:title="b"/>
  <div>This is the content for entry.</div>
</d:entry>

为此,我可以在某些编辑器中进行正则表达式替换,但需要多次完成,我想知道 Perl 是否有一些方法可以一次性完成。

标签: xmlperlcommand-lineduplicates

解决方案


以下是过滤掉重复项的常用方法:

my @filtered = grep { !$seen{$_}++ } @unfiltered;

这可以根据您的需要进行调整,如以下代码段所示:

my %seen;
for my $index_node ($xpc->findnodes('d:index', $entry_node)) {
   my $value = $xpc->findvalue('@d:value', $index_node);
   my $title = $xpc->findvalue('@d:title', $index_node);
   if ($seen{$value}{$title}++) {
      $index_node->unbind();
   }
}

(我使用了我喜欢的解析器 XML::LibXML,因为您没有提到您使用的是哪个解析器。)


推荐阅读