Perl 如何基于其父元素的属性获取XML子元素的文本内容

Perl 如何基于其父元素的属性获取XML子元素的文本内容,perl,xml-parsing,Perl,Xml Parsing,这是我的XML数据 <categories> <category id="Id001" name="Abcd"> <project> ID_1234</project> <project> ID_5678</project> </category> <category id="Id002" name="efgh"> <pro

这是我的XML数据

<categories>
    <category id="Id001" name="Abcd">
        <project> ID_1234</project>
        <project> ID_5678</project>
    </category>
    <category id="Id002" name="efgh">
        <project> ID_6756</project>
        <project> ID_4356</project>
    </category>
</categories>

这给了我数组
@catn
中的类别名称。但是我怎样才能得到每个项目的文本值呢?

您还没有展示到目前为止您已经尝试过的内容,或者您想要的输出是什么,所以我猜测了您在寻找什么

使用
XML::Twig
可以执行以下操作:

#!/usr/bin/env perl

use strict;
use warnings;

use XML::Twig;

my $twig = XML::Twig -> parse ( \*DATA );

foreach my $project ( $twig -> findnodes ( '//project' ) ) { 
    print join ",",  (map { $project -> parent -> att($_) } qw ( id name )), $project -> text,"\n"; 
}

__DATA__
<categories>
<category id="Id001" name="Abcd">
   <project> ID_1234</project>
   <project> ID_5678</project>
</category>
<category id="Id002" name="efgh">
   <project> ID_6756</project>
   <project> ID_4356</project>
</category>
</categories>
它通过使用
findnodes
定位任何元素“project”来实现这一点

然后从父元素(类别)中提取“id”和“name”属性,并将其与此特定元素中的文本一起打印

xpath
是从
XML
中选择数据的强大工具,通过更集中的问题,我们可以给出更具体的答案

因此,如果您正在查找“Abcd”类别下的所有项目,您可以:

foreach my $project ( $twig -> findnodes ( './category[@name="Abcd"]/project' ) ) { 
    print $project -> text,"\n";
}

你还没有展示到目前为止你已经尝试了什么,或者你想要的输出是什么,所以我猜测了你在寻找什么

使用
XML::Twig
可以执行以下操作:

#!/usr/bin/env perl

use strict;
use warnings;

use XML::Twig;

my $twig = XML::Twig -> parse ( \*DATA );

foreach my $project ( $twig -> findnodes ( '//project' ) ) { 
    print join ",",  (map { $project -> parent -> att($_) } qw ( id name )), $project -> text,"\n"; 
}

__DATA__
<categories>
<category id="Id001" name="Abcd">
   <project> ID_1234</project>
   <project> ID_5678</project>
</category>
<category id="Id002" name="efgh">
   <project> ID_6756</project>
   <project> ID_4356</project>
</category>
</categories>
它通过使用
findnodes
定位任何元素“project”来实现这一点

然后从父元素(类别)中提取“id”和“name”属性,并将其与此特定元素中的文本一起打印

xpath
是从
XML
中选择数据的强大工具,通过更集中的问题,我们可以给出更具体的答案

因此,如果您正在查找“Abcd”类别下的所有项目,您可以:

foreach my $project ( $twig -> findnodes ( './category[@name="Abcd"]/project' ) ) { 
    print $project -> text,"\n";
}

您可以尝试使用
XML::Simple

use strict;
use warnings;
use XML::Simple;
use Data::Dumper

my $XML_file  = 'your XML file';
my $XML_data;
#Get data from your XML file
open(my $IN, '<:encoding(UTF-8)', $XML_file) or die "cannot open file $XML_file";
{
   local $/;
   $XML_data = <$IN>;
}
close($IN);
#Store XML data as hash reference
my $xmlSimple = XML::Simple->new(KeepRoot   => 1);
my $hash_ref = $xmlSimple->XMLin($XML_data);
print Dumper $hash_ref;
现在要获取所需的数据,请执行以下操作:

foreach(@{$hash_ref->{'categories'}->{'category'}->{'Abcd'}->{'project'}}){
  print "$_\n";
}
结果是:

ID_1234
ID_5678

您可以尝试使用
XML::Simple

use strict;
use warnings;
use XML::Simple;
use Data::Dumper

my $XML_file  = 'your XML file';
my $XML_data;
#Get data from your XML file
open(my $IN, '<:encoding(UTF-8)', $XML_file) or die "cannot open file $XML_file";
{
   local $/;
   $XML_data = <$IN>;
}
close($IN);
#Store XML data as hash reference
my $xmlSimple = XML::Simple->new(KeepRoot   => 1);
my $hash_ref = $xmlSimple->XMLin($XML_data);
print Dumper $hash_ref;
现在要获取所需的数据,请执行以下操作:

foreach(@{$hash_ref->{'categories'}->{'category'}->{'Abcd'}->{'project'}}){
  print "$_\n";
}
结果是:

ID_1234
ID_5678

这将使用XML::LibXML,这是您已经在使用的库

您的
$cat
变量包含一个XML元素对象,您可以使用顶级
$doc
对象上使用的
findnodes()
findvalue()
方法来处理该对象

#!/usr/bin/perl

use strict;
use warnings;
# We use modern Perl here (specifically say())
use 5.010;

use XML::LibXML;

my $doc = XML::LibXML->new->parse_file('categories.xml');

foreach my $cat ($doc->findnodes('//category')) {
  say $cat->findvalue('@name');
  foreach my $proj ($cat->findnodes('project')) {
    say $proj->findvalue('.');
  }
}

这将使用XML::LibXML,这是您已经在使用的库

您的
$cat
变量包含一个XML元素对象,您可以使用顶级
$doc
对象上使用的
findnodes()
findvalue()
方法来处理该对象

#!/usr/bin/perl

use strict;
use warnings;
# We use modern Perl here (specifically say())
use 5.010;

use XML::LibXML;

my $doc = XML::LibXML->new->parse_file('categories.xml');

foreach my $cat ($doc->findnodes('//category')) {
  say $cat->findvalue('@name');
  foreach my $proj ($cat->findnodes('project')) {
    say $proj->findvalue('.');
  }
}

您正在使用哪个解析器?您好,我正在使用XML::LibXML来解析XML文件。您具体想要什么输出?代码方面,你已经有了什么?请包括你已经编写的代码,并解释你在哪里挣扎。你可以通过链接来回答你的问题。有关如何使用该站点的更多信息,请参阅。my$parser=XML::LibXML->new$doc=$parser->parse_文件(“/cctest/categories.xml”);my@nodes=$doc->findnodes('/categories/category');foreach my$cat(@nodes){您正在使用哪个解析器?您好,我正在使用XML::LibXML来解析XML文件。您特别想要什么输出?您已经有了什么,代码方面的?请包括您已经编写的代码,并解释您在哪里遇到了困难。您可以通过链接回答您的问题。有关如何使用网站的更多信息,请参阅。my$parser=XML::LibXML->new;$doc=$parser->parse_文件(“/cctest/categories.XML”);my@nodes=$doc->findnodes('/categories/categories');foreach my$cat(@nodes){您可以使用间接对象表示法(
new XML::Simple
)来推荐XML::Simple。您可以在a)推荐XML::Simple和b)使用间接对象表示法(
new XML::Simple
)上投反对票。嗨,我试过使用XML::Twig,它成功了。谢谢你的帮助:)嗨,我试过使用XML::Twig,它成功了。谢谢你的帮助:)@Dave Cross:非常感谢。即使是提供的代码也帮助我满足了我的要求。@Dave Cross:非常感谢。即使是提供的代码也帮助我满足了我的要求。