2

我只需要在 xml 文件中删除一些标签。

xml:

<p>Originally published <xref ref-type="bibr" rid="ref155">Klein, F. (1978)</xref> <i>Priam Books. Reproduced by permission of the author.</p>

脚本:

use XML::Twig;
my $xml_twig_content = XML::Twig->new(
keep_encoding => 1,
twig_handlers => {
keep_atts_order => 1,
'xref' => \&xref,
},
pretty_print => 'indented',
);
$xml_twig_content->parsefile('sample.xml');

sub xref {
 my ($xml_twig_content, $xref) = @_;
 my $XrefName = $xref->att('ref-type');
 if ($XrefName =~ /^bibr$/si){
 $xref->delete;
 }
}

我得到了输出:

<p>Originally published <i>Priam Books. Reproduced by permission of the author.</p>

我需要输出:

<p>Originally published Klein, F. (1978) <i>Priam Books. Reproduced by permission of the author.</p>

如何删除外部参照标签并保留其内容?

4

2 回答 2

3

您可以使用erase- 方法

erase

擦除元素:删除元素并将其所有子元素粘贴到其位置。

这是您的sub使用方法:

sub xref {
  my ( $twig, $xref ) = @_;
  $xref->erase;
}

请注意,对我来说,您的示例 XML 没有解析,因为<i>没有关闭。

于 2012-11-09T08:56:18.647 回答
2

为什么keep_encoding => 1位在位内twig_handlers?文档中是否有错误?

我会以更简单的方式执行此操作,使用twig_roots/twig_print_outside_roots传递除xref您感兴趣的 s 之外的所有内容:

#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;

XML::Twig->new( keep_encoding => 1,
                twig_roots => { 'xref[@ref-type=~/^(?i:bibr)/]' => sub { print $_->inner_xml; } },
                twig_print_outside_roots => 1,
              )
         ->parsefile('sample.xml');

twig_roots选项仅针对正确xref的 s 触发。该@ref-type=~/^(?i:bibr)/]位使用 XPath 的 XML::Twig 扩展,允许您像在 Perl 中一样使用正则表达式,该(?i:部分使其不区分大小写。对于这些元素,打印内部 XML,而不是标签。

twig_print_outside_roots选项(我知道这是一个很长的选项名称!)导致除外部参照元素之外的所有内容都按原样输出,因此您不必担心保持属性顺序或缩进,它将与原始 XML。

于 2012-11-09T10:44:38.100 回答