XML::LibXML を使用しています。XPath コンテキストを作成する際には、使用可能な名前空間を正確に指定できる必要があります。ただし、コンテキスト ノードのスコープ内のすべての名前空間は、XPathContext オブジェクトに自動的に登録されます。それらを登録解除する必要がありますが、コンテキスト ノードのスコープ内にある名前空間を登録解除しようとするとエラーが発生します。
use XML::LibXML;
use XML::LibXML::XPathContext;
my $xml = <<'__EOI__';
<?xml version="1.0"?>
<myDoc id="myDocId">
<body id="bodyId">
<baz:par xmlns:baz="www.baz.com"
xmlns:bar="www.bar.com">
<bar:id>xyz123</bar:id>
</baz:par>
</body>
</myDoc>
__EOI__
my $parser = XML::LibXML->new();
my $doc = $parser->parse_string($xml);
my $xpc = XML::LibXML::XPathContext->new();
$xpc->registerNs('baz', 'www.baz.com');
my $par = ${ $xpc->findnodes('//baz:par', $doc) }[0];
my $xpc2 = XML::LibXML::XPathContext->new($par);
$xpc2->unregisterNs('bar');
上記の鳴き声XPathContext: cannot unregister namespace
。ソースを調べると、LibXML.xsの 7618 行目からエラーが出力されていることがわかります。関数xmlXPathRegisterNs
が -1 を返したときに出力されます。私が見つけることができるこの関数の唯一のドキュメントはxmlsoft.orgにあります。このドキュメントでは、-1 の戻り値はエラーが発生したことを意味すると明記されていますが、エラーが発生する条件については明記されていません。私は一生、その方法のソースを見つけることができません。
XPath 仕様ではこの特定の操作が許可されていない可能性が非常に高いですが、それを判断することもできません。
a) XML::LibXML::XPathContext を使用してコンテキスト ノードのスコープ内の名前空間を登録解除する方法があるかどうか、または b) これが XPath で許可されていないというドキュメントがある場合は、誰にでも教えてもらえますか?
編集
Joel は、名前空間を手動で登録していない場合にのみ、名前空間の登録を解除すると特定のエラーがスローされることを示しました。ただし、登録解除はまだ正しく機能しません。
$xpc2->registerNs('bar', 'nothing'); #otherwise unregistering throws an error
$xpc2->unregisterNs('bar');
my @nodes = $xpc2->find('bar:id');
print scalar @nodes; #I want '0', but this prints '1'