【问题标题】:how can I parse an XML tag that has an attribute, using perl如何使用 perl 解析具有属性的 XML 标记
【发布时间】:2015-12-30 07:10:33
【问题描述】:

下面是一个 XML 文件,

   <?xml version='1.0'?>
    <employee>
      <name>Pradeep</name>
      <age>23</age>
      <sex>M</sex>
      <department>Coder</department>
    </employee>

而perl代码是

 use XML::Simple;
 use Data::Dumper;
 @xml=new XML::Simple;
 $data=@xml->XMLin("data.xml");
 print Dumper($data);

现在如果XML文件是你如何解析

   <?xml version='1.0'?>
      <employee="risc_31">
       <name>John Doe</name>
       <age>43</age>
       <sex>M</sex>
       <department>Analyst</department>
      </employee>
      <employee="risc_32">
       <name>Pradeep</name>
       <age>23</age>
       <sex>M</sex>
       <department>HR</department>
      </employee>

如何在 perl 中使用 foreach 循环来做到这一点

注意:XML::Simple 对我来说更容易

感谢任何帮助!

【问题讨论】:

  • 你错了。 XML::Simple 对任何人来说都不容易。 Why is XML::Simple discouraged
  • 谢谢!我将只使用 XML::Simple 来完成这项任务!一旦完成,我肯定会跳到 XML::Twig!@Sobrique

标签: xml perl parsing foreach


【解决方案1】:

你的xml无效,你不能拥有

<employee="risc_31">

你可以有类似的东西

<employee employeeId="risc_31">

假设你的 xml 是

<?xml version='1.0'?>
<employee employeeId="risc_31">
  <name>John Doe</name>
  <age>43</age>
  <sex>M</sex>
  <department>Analyst</department>
</employee>
<employee employeeId="risc_32">
  <name>Pradeep</name>
  <age>23</age>
  <sex>M</sex>
  <department>HR</department>
</employee>

您可以使用 libXML 执行以下操作(抱歉,我不知道 XML::Simple)

use strict;
use XML::LibXML;

my $filename = 'data.xml';
my $parser = XML::LibXML->new();
my $xmldoc = $parser -> parse_file( $filename );

foreach my $employee( $xmldoc -> findnodes( '/employee' ) ) {
  my $employeeId = $employee -> getAttribute( 'employeeId' );

  my $name = $employee -> findnodes( './name' );
  my $age = $employee -> findnodes( './age' );
  my $sex = $employee -> findnodes( './sex' );
  my $department = $employee -> findnodes( './department' );

}

exit 0;

【讨论】:

  • 没错,我的错!我们可以用 XML::Simple 来做吗?!如何做呢? @user1817991
  • 是的,我确信它可以使用 XML::Simple 完成,但我没有安装它,所以我无能为力,抱歉。
  • 不要 - 当有更好的替代品现成可用时,生命太短,无法与 XML::Simple 合作。 (XML::LibXML 在功能方面是最详尽的,XML::Twig 可能更容易上手)。 Why is XML::Simple discouraged
【解决方案2】:

XML 和 Perl 的问题。看看 Mac 上的 xmllint,我假设是 linux...

将 XML 视为具有两种类型的数据...“数据”和“元数据”,匹配的 ">ME ME ME 是元数据。将它们混合在一起意味着您会遇到错误,即 xmllint 向我展示了这一点

data.xml:2: parser error : error parsing attribute name
<employee="risc_31">
     ^
data.xml:2: parser error : attributes construct error
<employee="risc_31">
     ^
data.xml:2: parser error : Couldn't find end of Start Tag employee line 2
<employee="risc_31">
     ^
data.xml:2: parser error : Extra content at the end of the document
<employee="risc_31">
     ^

更改您的 XML 使其看起来更像。请注意,我已在此记录中添加了一个“wtf”条目,即我已将“risc_nn”数据作为员工记录的真实部分,而不是元数据...

<?xml version="1.0"?>
<foo>
<employee>
  <wtf>risc_31</wtf>
  <name>John Doe</name>
  <age>43</age>
  <sex>M</sex>
  <department>Analyst</department>
</employee>
<employee>
  <wtf>risc_32</wtf>
  <name>Pradeep</name>
  <age>23</age>
  <sex>M</sex>
  <department>HR</department>
  </employee>
</foo>

下面的 Perl 程序现在可以工作了

use strict;
use warnings;
use XML::Simple;
use Data::Dumper;
my @xml=new XML::Simple;
my $data=XMLin("data.xml");
print Dumper($data);

并提供以下结果...

$VAR1 = { 
    'employee' => {
        'John Doe' => {
            'wtf' => 'risc_31',
            'sex' => 'M',
            'department' => 'Analyst',
            'age' => '43'
     },  
     'Pradeep' => {
            'age' => '23',
            'wtf' => 'risc_32',
            'sex' => 'M',
            'department' => 'HR'
     }   
  }   
};

如果你想循环它是一个哈希引用,那么请使用以下...

for my $key (%{$data}) {
  print $data->{$key} . "\n";
}

或者在 Perl 中做任何事情的任何无数方法。

【讨论】:

  • 我知道这种方法,但我想试试我发布查询的方式!那更有趣;)
  • GRD - 上面的代码有一个 foreach 循环。 'for' 与'foreach' 相同。没有区别。
猜你喜欢
  • 1970-01-01
  • 2011-11-27
  • 1970-01-01
  • 2010-09-07
  • 1970-01-01
  • 1970-01-01
  • 2018-08-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多