2013-10-02 33 views
4

我想要一个perl脚本迭代一些节点并获取xml文件中的值。Perl脚本使用XML迭代xml节点:: LibXML

我的XML文件看起来像下面并保存spec.xml

<?xml version="1.0" encoding="UTF-8"?> 
<WO xmlns="http://www.example.com/yyyy" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > 
    <WOSet> 
    <SR> 
    <FINISHTIME>2013-07-29T18:21:38-05:00</FINISHTIME> 
    <STARTTIME xsi:nil="true" /> 
    <TYPE>SR</TYPE> 
    <DESCRIPTION>Create CUST</DESCRIPTION> 
    <EXTERNALSYSTEMID /> 
    <REPORTEDBY>PCAUSR</REPORTEDBY> 
    <REPORTEDEMAIL /> 
    <STATUS>RESOLVED</STATUS> 
    <SRID>1001</SRID> 
    <UID>1</UID> 
    <SPEC> 
     <AVALUE>IT</AVALUE> 
     <ATTRID>CUST_DEPT</ATTRID> 
     <NALUE xsi:nil="true" /> 
     <TVALUE /> 
    </SPEC> 
    <SPEC> 
     <AVALUE>001</AVALUE> 
     <ATTRID>DEPT_CODE</ATTRID> 
     <NVALUE xsi:nil="true" /> 
     <TVALUE /> 
    </SPEC> 
    </SR> 
</WOSet> 
    </WO> 

当我运行下面的脚本,我没有得到输出也没有任何错误得到就在哪里解决的事情线索...

我不是一个Perl的专家,会喜欢这里的专家通过一些轻...

#!/usr/bin/perl 
use XML::LibXML; 
use strict; 
use warnings; 
my $file = 'spec.xml'; 
my $parser = XML::LibXML->new(); 
my $tree = $parser->parse_file($file); 
my $root = $tree->getDocumentElement; 

foreach my $atrid ($tree->findnodes('WO/WOSet/SR/SPEC')) { 
    my $name = $atrid->findvalue('ATTRID'); 
    my $value = $atrid->findvalue('AVALUE'); 
    print $name 
    print " = "; 
    print $value; 
    print ";\n"; 
} 

我的预期输出是

CUST_DEPT = IT 
DEPT_CODE = 001 

回答

5

该XML在空名称空间中不包含任何名为WO的元素。您想匹配http://www.example.com/yyyy命名空间中名为WO的元素。

#!/usr/bin/perl 

use strict; 
use warnings; 

use XML::LibXML    qw(); 
use XML::LibXML::XPathContext qw(); 

my $file = 'spec.xml'; 

my $parser = XML::LibXML->new(); 
my $doc = $parser->parse_file($file); 
my $root = $doc->getDocumentElement; 

my $xpc = XML::LibXML::XPathContext->new($doc); 
$xpc->registerNs(y => 'http://www.example.com/yyyy'); 

for my $atrid ($xpc->findnodes('y:WO/y:WOSet/y:SR/y:SPEC')) { 
    my $name = $xpc->findvalue('y:ATTRID', $atrid); 
    my $value = $xpc->findvalue('y:AVALUE', $atrid); 
    print "$name = $value\n"; 
} 
+0

感谢您的回答......真的有用.. – user2190101

+0

我可以在这里要求一个额外的项目吗?这些输出是否可以存储在变量中(对于每次迭代)。我正在尝试varbel $结果来存储每个迭代的值,所以我可以将这些值作为一个字符串传递给我的脚本的下一个级别。预先感谢 – user2190101

+0

'push @results,[$ name,$ value];'在循环之外有'my @results;'?或者可能是一个散列('$ results {$ name} = $ value;'带'my%结果;')? – ikegami