【问题标题】:Accessing Sibling Elements in XML DOM using Perl?使用 Perl 访问 XML DOM 中的兄弟元素?
【发布时间】:2015-06-04 19:42:08
【问题描述】:

对于我的问题,我让用户输入一个字符串来搜索提供者,然后提供者以及一些选择计划信息出现在控制台中。但是,我不知道如何打印出选择的提供者 + 所需的其他信息。

例如:

沃达丰|| 12 个月 || 120GB

沃达丰|| 24 个月 || 200GB

我已经开始并且不太介意刺痛输入,因为我稍后会弄清楚,但我找不到如何首先搜索选择的提供程序然后打印信息。每个提供者和所有信息都在一个 节点中(参见下面的 XML)。

XML 文件

<plans>
    <internet>
        <plan>
            <technology>ADSL2+</technology>
            <length>12</length>
            <provider>Vodafone</provider>
            <price>60</price>
            <mincost>600</mincost>
            <data>120</data>
            <shaping>128</shaping>
            <homebundle>true</homebundle>
        </plan>
        <plan>
            <technology>ADSL2+</technology>
            <length>12</length>
            <provider>Telstra</provider>
            <price>80</price>
            <mincost>800</mincost>
            <data>200</data>
            <shaping>256</shaping>
            <homebundle>true</homebundle>
        </plan> 
        (etc.)

还有当前的 Perl 文件

use XML::DOM;

my $dom_obj;
my $xml_file= shift;

my $parser = new XML::DOM::Parser;

die "Unable to parse XML document\n" unless $dom_obj = $parser->parsefile($xml_file);

my @nodes = $dom_obj->getElementsByTagName("plan"); #return list of objects of 'Plan'

foreach $elem (@nodes) #for each 'Plan' object
{
    foreach $child ($elem->getChildElements) #should return each element under plan?
    {
        print $child->getNodeValue; #should print elements
        print " ";
    }
    print "\n";
} 

我尝试了一个 if 语句,以为我很接近,但只收到错误。

foreach $elem (@nodes)
{
    if($elem->getElementByTagName("provider")->getFirstChild->getNodeValue =~ /Vodafone/){
        print "$unit->getElementByTagName("provider")->getFirstChild->getNodeValue";
        print " || ";
        print "$unit->getElementByTagName("length")->getFirstChild->getNodeValue";
        print " || ";

任何帮助将不胜感激:)

【问题讨论】:

  • 你必须使用 XML::DOM 吗?

标签: xml perl


【解决方案1】:

我不熟悉XML::DOM,所以倾向于选择XML::Twig。像这样的:

#!/usr/bin/perl

use strict;
use warnings;
use XML::Twig;

my $provider = 'Vodafone';

sub print_plan_summary {
   my ( $twig, $plan ) = @_; 
   return unless $plan -> first_child_text('provider') eq $provider; 

   print join ( "||",  $plan -> first_child_text('provider'), 
                       $plan -> first_child_text('length')." months", 
                       $plan -> first_child_text('data'). " GB" );
}

my $twig = XML::Twig -> new ( twig_handlers => { 'plan' => \&print_plan_summary } ) -> parsefile('yourXML.xml');

XML::Twig 允许您设置处理程序,它采用 xml 的子集(在本例中为 plan 元素)并单独处理它们。因为我们可以做到这一点,所以我们可以随时进行操作,或者只是“简单地”从中提取数据。

【讨论】:

    【解决方案2】:

    如果您可以使用其他东西,使用XML::Simple 非常简单。通常我不喜欢 XML::Simple,但使用这种直接的 XML 结构,它确实可以工作。

    只需将文件(我把它放在__DATA__ 部分)读入数据结构,然后迭代计划。那些在arrayref中。现在您需要做的就是加入 hashref 值。

    use strict;
    use warnings;
    use feature 'say';
    use XML::Simple;
    
    my $xs   = XML::Simple->new;
    my $data = $xs->XMLin( \*DATA );
    
    
    foreach my $plan ( @{ $data->{internet}->{plan} } ) {
        next if $plan->{provider} ne 'Vodafone';
        say join q{ || }, $plan->{provider}, $plan->{length} . ' months', $plan->{data} . 'gb';
    }
    

    【讨论】:

    • 就个人而言 - 我并不热衷于建议人们使用 XML::Simple。甚至模块页面也建议不要这样做。
    • @Sobrique 我知道。这就是为什么我在顶部有免责声明。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-28
    • 1970-01-01
    • 2019-04-16
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多