<Root>
<Top Name=" ">
<Tag name="ALU">
<in name="PC"/>
<iodirection name="AB"/>
</Tag>
<Tag name=" ">
<in name="CCB"/>
<ou name="PC"/>
<bi name="AB"/>
</Tag>
<Tag name=" ">
<in name="DB"/>
<ou name="DI"/>
<bi name="CCB"/>
</Tag>
<Tag name=" ">
<in name="DI"/>
<ou name="DB"/>
<bi name="CCB"/>
</Tag>
</Top>
</Root>
我不是Perl专家,但是我很难弄清楚一些简单的事情,其中一个任务就是这样。上面的XML,您可以看到属性/元素,它们重复了几次,但适用于不同的<in>
,<io>
和<ou>
标记。现在,我希望只返回重复的属性/元素,只打印一次。
Example : DI
DB
CCB
AB
我的代码段就是这样的
use strict;
use XML::Simple;
use Data::Dumper;
$xml_1 = XMLin('./tmp.xml');
my $root_top = $xml_1->{Top};
my $mod_top = $root_top1->{Tag};
my @mod = keys %$mod_top;
foreach my $mods ( values %$mod_top ) {
my $temp = shift(@mod);
print XST_FILE "$temp u_$temp(\n";
my $in_mo = $modules->{in};
my @in_1 = keys %$in_mo;
foreach my $name_1 ( values %$in_mo ) {
my $inn = shift(@in_1);
if ( $inn =~ /\bname\b/ ) {
print " \.$name_1\($name_1\)\,\n";
}
else {
print " \.$in\($in\)\,\n";
}
}
PS:如果只能在XML::Simple
修改,我会很感激。虽然XML::Simple is discouraged,但他并不是正义的,但他是我目前用来完成这项任务的人
答案 0 :(得分:4)
不要使用XML :: Simple。
#! /usr/bin/perl
use warnings;
use strict;
use feature qw{ say };
use XML::LibXML;
my $xml = 'XML::LibXML'->load_xml(location => shift);
my %names;
$names{ $_->value } = 1 for $xml->findnodes('//*[not(*)]/@name'); # Leaf nodes only.
say for keys %names;
答案 1 :(得分:2)
这是一个使用XML::LibXML
来满足要求的程序。它使用单个XPath表达式来查找感兴趣的所有属性,并以散列%names
计算它们。随后的for
循环显示计数大于1的所有散列键
use strict;
use warnings 'all';
use XML::LibXML;
my $xml = XML::LibXML->load_xml(IO => \*DATA);
my %names;
++$names{ $_->getValue } for $xml->findnodes('//in/@name | //ou/@name | //bi/@name');
print "$_\n" for grep { $names{$_} > 1 } keys %names;
__DATA__
<Root>
<Top Name=" ">
<Tag name="ALU">
<in name="PC"/>
<iodirection name="AB"/>
</Tag>
<Tag name=" ">
<in name="CCB"/>
<ou name="PC"/>
<bi name="AB"/>
</Tag>
<Tag name=" ">
<in name="DB"/>
<ou name="DI"/>
<bi name="CCB"/>
</Tag>
<Tag name=" ">
<in name="DI"/>
<ou name="DB"/>
<bi name="CCB"/>
</Tag>
</Top>
</Root>
DB
PC
DI
CCB