xmllintを使用して名前空間を持つxmlから属性値を取得する

xmllintを使用して名前空間を持つxmlから属性値を取得する

xpathオプションを使用して(xmllint 'シェルを使用せずに)属性値を取得したいと思います。

私の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

関連情報