从使用命名空间的XML文档中提取数据

Roy*_*yeh 9 xml perl xml-libxml

我有一些XML文件,我想从中使用一些信息.我编写了一个代码来读取这些文件,然后查找一些条件.

问题是这些XML文件以

   <SquishReport version="2.1" xmlns="http://www.froglogic.com/XML2">
Run Code Online (Sandbox Code Playgroud)

并且Perl无法读取它们(至少在我的代码中!).但是当我在XML文件的第一行附加这些行时

   <?xml version="1.0" encoding="UTF-8"?>
   <?xml-stylesheet type="text/xsl"?>
Run Code Online (Sandbox Code Playgroud)

效果很好.

我的XML文件中的一些行test.xml:

<SquishReport version="2.1" xmlns="http://www.froglogic.com/XML2">
   <test name="TEST">
      <prolog time="2015-10-01T03:45:22+02:00"/>
      <test name="tst_start_app">
          <prolog time="2015-02-01T03:45:23+02:00"/>
          <message line="38" type="LOG" file="C:\squish\test\sources.py" time="2015-02-01T03:45:23+02:00">
              <description>
                <![CDATA[>>  >>  >> start: init (global) - testcase C:\squish\test\tst_start_app]]></description>
          </message>
       </test>
   </test>
</SquishReport>
Run Code Online (Sandbox Code Playgroud)

并且用于读取XML文件的Perl代码是:

use strict;
use warnings;
use feature 'say';
use XML::LibXML;

# Parse the XML
my $xml = XML::LibXML->load_xml(location => 'test.xml');

# Iterate the entries
for my $entry ($xml->findnodes('/SquishReport/test/test')) {
    my $key = $entry->findvalue('@name');
    say "$key";
}
Run Code Online (Sandbox Code Playgroud)

ike*_*ami 12

该文档的根节点是具有名称的元素SquishReporthttp://www.froglogic.com/XML2命名空间.简而言之,我们可以说根节点是一个

{http://www.froglogic.com/XML2}SquishReport
Run Code Online (Sandbox Code Playgroud)


当在XPath中使用SquishReport(而不是prefix:SquishReport)时,尝试匹配SquishReportnull命名空间中具有名称的元素.简而言之,我们可以说它试图匹配一个

{}SquishReport
Run Code Online (Sandbox Code Playgroud)


要指定命名空间,可以使用在上下文中定义的前缀,如下所示:

use strict;
use warnings;
use feature qw( say );

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

my $xpc = XML::LibXML::XPathContext->new();
$xpc->registerNs(sr => 'http://www.froglogic.com/XML2');

my $doc = XML::LibXML->load_xml( location => 'test.xml' );
for my $entry ($xpc->findnodes('/sr:SquishReport/sr:test/sr:test', $doc)) {
    my $key = $entry->findvalue('@name');
    say $key;
}
Run Code Online (Sandbox Code Playgroud)


注意:XPath中使用的前缀与XML文档中使用的前缀(如果有)无关.您需要知道要搜索的元素所在的命名空间,而不是给定文档使用的前缀.