使用 xmllint 从带有命名空间的 xml 中检索属性值

使用 xmllint 从带有命名空间的 xml 中检索属性值

我想使用 xpath 选项检索属性值(不使用 xmllint' shell)。

我的XML:

<?xml version="1.0" encoding="UTF-8"?>
<XML>
    <hhi:Elem xmlns:hhi="http://www.w3.org/TR/html4/" version="1.0" sn="101"> 
    </hhi:Elem>
</XML>

这是我尝试过的:

xmllint --xpath '//XML/*[local-name()='Elem']/@sn' FILE_1.xml
XPath set is empty

xmllint --xpath '//XML/*[local-name()='Elem' and namespace-uri()="http://www.w3.org/TR/html4/"]/@sn' FILE_1.xml
XPath set is empty

(我知道我可以使用 sed 来删除名称空间,但我也想避免这种情况)

答案1

是的,不要sed在 上使用XML。这是个坏消息。

我认为你的问题实际上是一个简单的引用问题 - 你xpath用单引号引用你的内容,并且Elem也用单引号引用。

我没有xmllint方便的副本,但这有效:

#!/usr/env/perl

use strict;
use warnings;

use XML::LibXML;

my $xml = XML::LibXML -> load_xml ( IO => \*DATA ); 
print $xml -> findnodes('//XML/*[local-name()="Elem"]');

__DATA__
<?xml version="1.0" encoding="UTF-8"?>
<XML>
    <hhi:Elem xmlns:hhi="http://www.w3.org/TR/html4/" version="1.0" sn="101"> 
    </hhi:Elem>
</XML>

打印:

sn="101"

您也不需要XML,因为//表示“树中的任何位置”。所以你可以使用:

//*[local-name()="Elem"]/@sn
/XML/*[local-name()="Elem"]/@sn

为了完整起见,通过注册命名空间,您可以这样做:

#!/usr/env/perl

use strict;
use warnings;

use XML::LibXML;

my $xml = XML::LibXML -> load_xml ( IO => \*DATA ); 
my $xpc = XML::LibXML::XPathContext -> new;
$xpc -> registerNs('x', 'http://www.w3.org/TR/html4/');
print $xpc -> findnodes('/XML/x:Elem/@sn', $xml);

__DATA__
<?xml version="1.0" encoding="UTF-8"?>
<XML>
    <hhi:Elem xmlns:hhi="http://www.w3.org/TR/html4/" version="1.0" sn="101"> 
    </hhi:Elem>
</XML>

xmllint现在,我知道除了允许测试您xpath正在使用的之外,这并没有直接帮助。但我认为很可能是引号让你绊倒,而不是xpath.

我可以建议您需要:

xmllint --xpath '//*[local-name()="Elem"]/@sn' FILE_1.xml

相关内容