如何在perl中从xml中获取所需元素?

如何在perl中从xml中获取所需元素?,xml,perl,Xml,Perl,我想要一个perl中的方法来执行以下操作 示例xml文件 <?xml version="1.0"?> <data> <country name="Liechtenstein"> <rank>1</rank> <year>2008</year> <gdppc>141100</gdppc> <neighbor nam

我想要一个perl中的方法来执行以下操作 示例xml文件

<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/> First Country
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/> Second Country
    </country>
    <country name="Panama">
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/> Third Country
    </country>
</data>

1.
2008
141100
第一个国家
4.
2011
59900
第二个国家
68
2011
13600
第三国
当我输入elmentrank作为输入时,输出应该如下所示

<?xml version="1.0"?>
    <data>
        <country name="Liechtenstein">
            <rank>1</rank>
        </country>
        <country name="Singapore">
            <rank>4</rank>
        </country>
        <country name="Panama">
            <rank>68</rank>
        </country>
    </data>

1.
4.
68
使用XML::Twig:

#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;

my $tag= shift @ARGV;
my $xml_file= shift @ARGV;

XML::Twig->new( twig_handlers => 
                  { 'country' => sub { foreach my $c ($_->children) 
                                         { $c->delete unless $c->is( $tag); } 
                                     },
                  },
                 pretty_print => 'indented',
              )->parsefile( $xml_file )
               ->print;

您可以使用Perl+XSLT来完成。首先,您需要一个XSLT文档。下面的一个实现了您所需的转换(您可以对其进行测试):

这种转变的结果是:

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <country name="Liechtenstein">
      <rank>1</rank>
   </country>
    <country name="Singapore">
      <rank>4</rank>
   </country>
    <country name="Panama">
      <rank>68</rank>
   </country>
</data>

1.
4.
68
此解决方案使用并通过查找具有所需节点名的每个
国家/地区
元素的子元素来工作,然后删除所有子元素并添加回所选元素

use strict;
use warnings;

use XML::LibXML;

my $doc = XML::LibXML->load_xml(IO => *DATA, no_blanks => 1);

my $nodename = 'rank';

for my $country ($doc->findnodes('/data/country')) {
  my ($node) = $country->findnodes($nodename);
  $country->removeChildNodes;
  $country->appendChild($node);
}

print $doc->toString(1);

__DATA__
<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/> First Country
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/> Second Country
    </country>
    <country name="Panama">
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/> Third Country
    </country>
</data>
使用严格;
使用警告;
使用XML::LibXML;
my$doc=XML::LibXML->load_-XML(IO=>*数据,无空格=>1);
我的$nodename='rank';
对于我的$country($doc->findnodes('/data/country')){
我的($node)=$country->findnodes($nodename);
$country->removeChildNodes;
$country->appendChild($node);
}
打印$doc->toString(1);
__资料__
1.
2008
141100
第一个国家
4.
2011
59900
第二个国家
68
2011
13600
第三国
输出

<?xml version="1.0"?>
<data>
  <country name="Liechtenstein">
    <rank>1</rank>
  </country>
  <country name="Singapore">
    <rank>4</rank>
  </country>
  <country name="Panama">
    <rank>68</rank>
  </country>
</data>

1.
4.
68

使用XLST文档可以非常轻松地进行转换。我不想硬编码xml,我想处理大量的xmlfiles@Venkatesan:是的,我知道,但你知道如何打开文件,对吗?
use strict;
use warnings;

use XML::LibXML;

my $doc = XML::LibXML->load_xml(IO => *DATA, no_blanks => 1);

my $nodename = 'rank';

for my $country ($doc->findnodes('/data/country')) {
  my ($node) = $country->findnodes($nodename);
  $country->removeChildNodes;
  $country->appendChild($node);
}

print $doc->toString(1);

__DATA__
<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank>1</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/> First Country
    </country>
    <country name="Singapore">
        <rank>4</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/> Second Country
    </country>
    <country name="Panama">
        <rank>68</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/> Third Country
    </country>
</data>
<?xml version="1.0"?>
<data>
  <country name="Liechtenstein">
    <rank>1</rank>
  </country>
  <country name="Singapore">
    <rank>4</rank>
  </country>
  <country name="Panama">
    <rank>68</rank>
  </country>
</data>