【问题标题】:Count duplicate XML attribute values using XML::Simple使用 XML::Simple 计算重复的 XML 属性值
【发布时间】:2016-01-19 13:38:44
【问题描述】:
<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 属性/元素重复了几次,但针对不同的 &lt;in&gt;&lt;io&gt;&lt;ou&gt; 标签。现在我希望只返回重复的属性/元素并打印一次。

Example : DI
          DB
          CCB
          AB

我的代码 sn-p 是这样的

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,他并不正义,但他是我目前用来完成这项任务的人

【问题讨论】:

  • 你的问题标题很糟糕。请edit您的问题并更改标题以说出您想做什么。点击诱饵在这里不起作用。我也不明白你真正想要做什么。另外,你有use strict很好,但是你的代码不会编译。请更改代码并使其工作,并在您使用时缩进。
  • “我的代码 sn-p 是这样的” 你为什么发布类似你的实际代码?您所展示的内容无法编译,如果我们正在处理与真实问题不同的问题,我们没有机会帮助您

标签: xml perl foreach


【解决方案1】:

不要使用 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;

【讨论】:

  • 这包括元素 name 的属性 iodirection 并打印所有值,无论其频率如何
【解决方案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

【讨论】:

    猜你喜欢
    • 2013-07-29
    • 2016-07-21
    • 1970-01-01
    • 2010-10-14
    • 2012-06-10
    • 2021-10-18
    • 1970-01-01
    • 1970-01-01
    • 2010-10-14
    相关资源
    最近更新 更多