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

从使用名称空间的XML文档中提取数据,xml,perl,xml-libxml,Xml,Perl,Xml Libxml,我有一些XML文件,我想使用其中的一些信息。我编写了一段代码,读取这些文件,然后查找一些条件 问题是这些XML文件以 <SquishReport version="2.1" xmlns="http://www.froglogic.com/XML2"> 效果很好 我的XML文件test.XML中的一些行: <SquishReport version="2.1" xmlns="http://www.froglogic.com/XML2"> <test na

我有一些XML文件,我想使用其中的一些信息。我编写了一段代码,读取这些文件,然后查找一些条件

问题是这些XML文件以

   <SquishReport version="2.1" xmlns="http://www.froglogic.com/XML2">
效果很好

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

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

{http://www.froglogic.com/XML2}喷射器

在XPath中使用
SquishReport
(与
前缀:SquishReport
相反)时,它会尝试匹配在空命名空间中具有名称
SquishReport
的元素。简而言之,我们可以说它试图匹配

{}SquishReport

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

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


注意:XPath中使用的前缀与XML文档中使用的前缀(如果有)没有关系。您应该知道您要搜索的元素所在的名称空间,但不知道给定文档使用的前缀。

Perl有这么多优秀的XML工具,多亏了所有的模块开发人员,XML看起来很容易。其中一个工具是-一个方便的“脚手架”模块,它构建在
XML::LibXML
的基础上,并使用“概要文件”标记语言从XML源获取数据(NB:概要文件标记对空格和行尾敏感)

e、 g:

输出:

\ [
    [0] {
        name   "tst_start_app"
    }
]

非常感谢你的回答!!这真的很干净!我倾向于使用由
XML::LibXML
构建的模块,但您让它看起来很简单。XML永远不会消失,perl有一些非常强大的工具来处理它。可能的重复请不要像那个问题的重复那样结束。该问题的XML是非法的,使问题复杂化,使该问题的解决方案与该问题无关。我想把这个问题作为一个清晰的例子。
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;
}
use XML::Dataset;
use DDP;

my $xml = "Squish.xml" ; 
open my $fh, "<", $xml or die "aiiieee!";
my $test_data = do { local $/; <$fh> };

# describe the data using XML::Dataset simplified markup:
my $data_profile
    = q(
          SquishReport
            test
              test
                 name = dataset:name);

# parse it with XML::Dataset profile
my $parsed_data = parse_using_profile($test_data, $data_profile);

# view the element with Data::Printer
foreach my $element ( $parsed_data->{name}){
     p $element ;
};
<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>
\ [
    [0] {
        name   "tst_start_app"
    }
]