XML::LibXML 为具有命名空间前缀的属性查找值

XML::LibXML findvalue for an attribute with a namespace prefix

我在使用时遇到了一些问题 XML::LibXML 与命名空间。我之前分析过带有命名空间的文件,但这个有点不同,因为它是用 xlmns:abc 定义的,而不是 xlmns.

我无法从此元素中提取 abc:id893

<element name='THEFIELD' type='string' abc:id='893' minOccurs='0' maxOccurs='1'>

示例数据

<schema
    xmlns:abc="http://www.example.com/schemas/abc"
    targetNamespace="http://example.com/schemas/product"
    elementFormDefault="qualified">

  <TheType name='MyName'>
    <sequence>
      <element name='THEFIELD' type='string' abc:id='893' minOccurs='0' maxOccurs='1'>
        <annotation><documentation>Identifier - Realtime</documentation></annotation>
      </element>

我的代码 returns 所有值都正确(nametype 属性)但 abc:id

#!/usr/bin/perl

use 5.010;
use strict;
use warnings;

use XML::LibXML;
use XML::LibXML::XPathContext;

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

my $xpc = XML::LibXML::XPathContext->new( $dom );
$xpc->registerNs( 'ns', 'abc:http://www.example.com/schemas/abc' );

foreach my $title ( $xpc->findnodes( '//schema' ) ) {

    foreach my $title ( $xpc->findnodes( '//TheType[@name="MyName"]/sequence/element' ) ) {

        say $title->findvalue( './@name' ), '|', $title->findvalue( '??????' ), '|', $title->findvalue( './@type' );
    }
}

我的想法是

我在这里尝试了很多东西,包括 ns:/@id*[local-name()="id"]

XML::LibXML::XPathContext doesn't have to be used (in the recent years), it's loaded with XML::LibXML.

registerNs函数的正确用法是给它一个前缀和URI。

对嵌套循环使用相同的变量没有任何意义,尤其是当您不在任何地方使用外部变量时。

您可以使用 join 来避免重复调用 findvalue

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

use XML::LibXML;

my $filename = shift;
my $dom = 'XML::LibXML'->load_xml(location => $filename);

my $xpc = 'XML::LibXML::XPathContext'->new($dom);
$xpc->registerNs(abc => 'http://www.example.com/schemas/abc');

for my $title ($xpc->findnodes('//TheType[@name="MyName"]/sequence/element')) {
    say join '|', map $title->findvalue($_), '@name', '@abc:id', '@type';
}