今天我一直在努力解决这个问题。尝试读取下面的XML文件(我很快就输入了)。我有一个show_id
代码的CSV文件。所以我读了它们并将它们放入哈希。然后我使用XML::Simple
读取XML文件。
然后我比较了元素中的show_id
代码(在在线示例中完成了一个数组的循环,然后在$a = $data->{Element1}->{Element2}->{show_id}
找到了它),看看我是否匹配了哈希表。答对了。我没有问题就可以了。
因此,假设我将中间两个Element2
元素与show_id
和ABC11
的{{1}}值进行匹配。现在我需要写一个匹配的新文件。所以我尝试了ABC12
,我似乎失去了我读过的整个标签结构。
有没有办法读取下面的数据并删除记录XMLout
和ABC10
,并以相同的格式删除文件?如果这是有道理的,请告诉我。
此外,我只在工作时安装了ABC14
和XML::Simple
。请帮助!!!
XML::Parser
答案 0 :(得分:2)
如果你能得到
XML::Twig
已安装,这是您可能更喜欢的解决方案。
use strict;
use warnings;
use XML::Twig;
my %keep = (
ABC11 => 1,
ABC12 => 1,
);
my $twig = XML::Twig->new(
keep_spaces => 1,
twig_handlers => { Element2 => \&Element2 }
);
$twig->parsefile('data.xml');
$twig->print;
sub Element2 {
my ($twig, $elem) = @_;
my $show_id = $elem->first_child_text('show_id');
$elem->delete unless $keep{$show_id};
}
或者如果您愿意
XML::LibXML
那么这将有效
use strict;
use warnings;
use XML::LibXML;
my %keep = (
ABC11 => 1,
ABC12 => 1,
);
my $xml = XML::LibXML->load_xml(location => 'data.xml');
for my $elem2 ($xml->findnodes('//Element2')) {
my $show_id = $elem2->find('show_id');
$elem2->parentNode->removeChild($elem2) unless $keep{$show_id};
}
print $xml->toString;
这些程序的输出完全相同。
<强>输出强>
<?xml version="1.0" encoding="ISO-8859-1"?>
<main>
<Element1>
<Element2>
<show/>
<show_id>ABC11</show_id>
<staring>
<show_header>This is a test</show_header>
</staring>
</Element2>
<Element2>
<show/>
<show_id>ABC12</show_id>
<staring>
<show_header>This is a test</show_header>
</staring>
</Element2>
</Element1>
</main>
答案 1 :(得分:1)
首先,摆脱废弃的元素:
$data->{Element1}{Element2} = [
grep { $_->{show_id} =~ /^ABC1[12]$/ } @{$data->{Element1}{Element2}}
];
然后,以XML格式写出来。 (对于NoAttr => 1
,哈希表示为嵌套元素而不是属性。)
print XMLout($data, NoAttr => 1, RootName => "main");
您可以将KeepRoot => 1
传递给XMLin和XMLout来处理根元素(“main”)而不是RootName => 1
。如果您这样做,请使用$data->{main}{Element1}{Element2}
。
答案 2 :(得分:1)
如果你想要同样的东西出来,不要使用XML :: Simple。以下是使用XML::Rules的解决方案:
use strict;
use warnings;
use XML::Rules;
my @keep_these = qw(
ABC11
ABC12
);
my %keep; $keep{$_}++ for @keep_these;
my @rules = (
Element2 => sub {
my $id = $_[1]->{show_id}{_content};
return unless $keep{$id};
return $_[0] => $_[1];
},
);
my $p = XML::Rules->new(
style => 'filter',
rules => \@rules,
stripspaces => 3,
);
$p->filter(\*DATA, \*STDOUT);
__END__
<?xml version="1.0" encoding="ISO-8859-1"?>
<main>
<Element1>
<Element2>
etc.