【问题标题】:Parsing an special xml file using perl使用 perl 解析特殊的 xml 文件
【发布时间】:2016-09-25 17:50:10
【问题描述】:

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

<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>

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

这是我尝试过的代码:-

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;

}

输出:- 无法在 ./test2.pl 第 6 行对未定义值调用方法“getNodeValue”。

我是否遗漏了什么或走错了方向?

请帮忙。 提前致谢!

:更新:

如果我要如下更改我的 xml 文件,

<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 的值,这样它才能获取$BranchBatman

【问题讨论】:

标签: xml perl parsing


【解决方案1】:

问题是$entry-&gt;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 对此的回答。

【讨论】:

    【解决方案2】:

    当您想在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 ;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-30
      • 2017-10-28
      • 2013-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多