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

관련 정보