使用perl解析一个特殊的xml文件

时间:2016-09-25 17:50:10

标签: xml perl parsing

我正在尝试解析xml文件,并获取bBranch,Branch ...

的值
public function actionOne($id)
{           
    $modelMyEntity = $this->findModel($id);
    $modelMyEntity->scenario = 'scenario_one';
    .
    .
    .
}

public function actionTwo($id)
{           
    $modelMyEntity = $this->findModel($id);
    $modelMyEntity->scenario = 'scenario_two';
    .
    .
    .
}

我尝试过使用XML:LibXML和XML :: DOM

这是我尝试过的代码: -

<xml-fragment xmlns:con="http://some web link">
  <con:properties>

        <con:string name="bBranch" value="in" export="never" />
        <con:string name="Branch" value="in" export="never" />

        <con:boolean name="cBranch" value="0" export="never" />
  </con:properties>
</xml-fragment>

输出: - 无法调用方法&#34; getNodeValue&#34;在./test2.pl第6行的未定义值。

我错过了什么或走向错误的方向吗?

请帮忙。 提前谢谢!

:UPDATE:

如果我按如下方式更改我的xml文件,

use XML::DOM;
my $file ="above.xml";
my $parser = XML::DOM::Parser->new();

my $doc = $parser->parsefile($file);

foreach my $entry ($doc->getElementsByTagName('con:properties')) {
        my $parent = $entry->getElementsByTagName('con:string')->item(0)->getFirstChild->getNodeValue;
        print $parent;

}

如何获取<xml-fragment xmlns:con="http://some web link"> <con:properties> <con:string name="Branch" value="Batman" export="never" /> <con:boolean name="cBranch" value="$Branch" export="never" /> </con:properties> </xml-fragment> 的值,使其获取cBranch$Branch

2 个答案:

答案 0 :(得分:0)

如果您要使用XML::LibXML中的命名空间,则需要使用XML::LibXML::XPathContext

#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

use XML::LibXML;

my $dom = 'XML::LibXML'->load_xml(location => 'above.xml');

my $xpc = 'XML::LibXML::XPathContext'->new;
$xpc->registerNs('con', 'http://some%20web%20link');

for my $property ($xpc->findnodes('//con:properties', $dom)) {
    my @names = $xpc->findnodes('con:string/@name', $property);
    say join ' ', map $_->getValue, @names;
}

xsh中缩短了一点:

open above.xml ;
register-namespace con http://some%20web%20link ;
echo //con:properties/con:string/@name ;

答案 1 :(得分:0)

问题是$entry->getElementsByTagName('con:string')返回一个数组,所以你需要在你拥有的第二个循环中。所以你可以这样做:

foreach my $entry ($doc->getElementsByTagName('con:properties')) {
        foreach my $elem ($entry->getElementsByTagName('con:string')) {
                my $name = $elem->getAttribute('name');
                my $value = $elem->getAttribute('value');
                print "$name = $value\n";
    }
}

请注意,从xml文档中提取类似的信息非常繁琐,因此您可能希望寻找一种允许您使用xpath访问文档部分的解决方案。另见choroba的答案。