我嘗試向 XML (svg) 檔案添加一個新節點,但是當我之后嘗試使用 XPath 運算式查詢它時,它沒有找到新節點。
use strict;
use warnings;
use XML::LibXML;
use XML::LibXML::XPathContext;
my $parser = XML::LibXML->new();
my $svg = $parser->load_xml(string => <<'SVG');
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">
<g inkscape:groupmode="layer" id="old-id" inkscape:label="old-label">...</g>
</svg>
SVG
my $layer = XML::LibXML::Element->new('g'); # same result with 'svg:g'
$layer->setAttribute('inkscape:groupmode', 'layer');
$layer->setAttribute('id', 'new-id');
$layer->setAttribute('inkscape:label', 'new-label');
$svg->documentElement()->appendChild($layer);
print "Dump:\n$svg\n";
print "Xpath:\n";
my $xpc = XML::LibXML::XPathContext->new($svg);
$xpc->registerNs('svg', 'http://www.w3.org/2000/svg');
my $xpath = '//svg:g';
foreach my $node ($xpc->findnodes($xpath)) {
print $node->getAttribute('id'), ": ", $node->getAttribute('inkscape:label'), "\n";
}
這列印:
Dump:
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">
<g inkscape:groupmode="layer" id="old-id" inkscape:label="old-label">initially</g>
<g inkscape:groupmode="layer" inkscape:label="new-label" id="new-id"/></svg>
Xpath:
old-id: old-label
當我轉儲整個 xml 檔案時會出現新節點,但 XPath 運算式僅報告舊節點。
為什么會這樣,我如何讓 XPath 運算式也找到新添加的節點?
uj5u.com熱心網友回復:
當您的列印陳述句輸出 XML 時,如果重新決議該 XML 將為您提供正確的結果,但您的記憶體 DOM 不知道新元素的名稱空間。要告訴新元素有關命名空間的資訊,我們可以使用SetNamespace和SetAttributeNS根據檔案
use strict;
use warnings;
use XML::LibXML;
use XML::LibXML::XPathContext;
my $parser = XML::LibXML->new();
my $svg = $parser->load_xml(string => <<'SVG');
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">
<g inkscape:groupmode="layer" id="old-id" inkscape:label="old-label">...</g>
</svg>
SVG
my $layer = XML::LibXML::Element->new('g'); # same result with 'svg:g'
$layer->setNamespace('http://www.w3.org/2000/svg');
$layer->setNamespace('http://www.inkscape.org/namespaces/inkscape', 'inkscape', 0);
$layer->setAttributeNS('http://www.inkscape.org/namespaces/inkscape', 'groupmode', 'layer');
$layer->setAttribute('id', 'new-id');
$layer->setAttributeNS('http://www.inkscape.org/namespaces/inkscape', 'label', 'new-label');
$svg->documentElement()->appendChild($layer);
print "Dump:\n$svg\n";
print "Xpath:\n";
my $xpc = XML::LibXML::XPathContext->new($svg);
$xpc->registerNs('svg', 'http://www.w3.org/2000/svg');
my $xpath = '//svg:g';
foreach my $node ($xpc->findnodes($xpath)) {
print $node->getAttribute('id'), ": ", $node->getAttribute('inkscape:label'), "\n";
}
輸出
Dump:
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape">
<g inkscape:groupmode="layer" id="old-id" inkscape:label="old-label">...</g>
<g inkscape:groupmode="layer" id="new-id" inkscape:label="new-label"/></svg>
Xpath:
old-id: old-label
new-id: new-label
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/316251.html
