在下面的代码中,我试图解析一个 SVG 文件并删除其中的所有文本节点。 但是,它不起作用(代码永远不会进入 findnodes 的 forloop)。我究竟做错了什么?我尝试使用代码的 XPath 和 LibXML 版本,但它们都不起作用。他们可以很好地解析和转储文件,但 findnodes 不匹配任何内容。
#!/usr/bin/perl
use strict;
use warnings;
use XML::XPath;
use XML::XPath::XMLParser;
my $num_args=$#ARGV+1;
if($num_args != 1) { print "Usage: $0 <filename>\n"; exit(1); }
my $file=$ARGV[0];
my $doc = XML::XPath->new(filename => $file);
foreach my $dead ($doc->findnodes('/svg/text')) {
print "Found Text Node\n";
$dead->unbindNode;
}
开始 SVG 文件的几行:
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
width="675"
height="832.5"
id="svg2"
xml:space="preserve"><metadata
id="metadata8"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs6" /><g
transform="matrix(1.25,0,0,-1.25,0,832.5)"
id="g10"><path
d="m 54,608.663 450,0 M 54,129.052 l 450,0"
inkscape:connector-curvature="0"
id="path12"
style="fill:none;stroke:#231f20;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none" /><text
transform="matrix(1,0,0,-1,229.0848,615.9133)"
id="text14"><tspan
@
最佳答案
/svg/text
直接在 svg
根元素下查找 text
元素。那不是你在这里拥有的。看起来您想要的是文档中任意位置的 text
元素,即 //text
。这应该与 XML::XPath 一起工作。
如果你想使用 XML::LibXML,你应该使用它,因为它是一个比 XML::XPath 好得多的模块(更好维护、更高效、更强大),那么你必须注意命名空间:整个文档有一个默认命名空间(开始标记中的 xmlns="http://www.w3.org/2000/svg"
位)。您将需要声明它并使用 XML::LibXML::XPathContext 来计算 XPath 表达式,包括前缀。:
#!/usr/bin/perl
use strict;
use warnings;
use XML::LibXML;
use XML::LibXML::XPathContext;
# it's easier to test directly @ARGV in scalar context than to use $#ARGV
if(@ARGV != 1) { print "Usage: $0 <filename>\n"; exit(1); }
my $file=$ARGV[0];
my $doc = XML::LibXML->load_xml( location => $file);
my $xpc = XML::LibXML::XPathContext->new( $doc); # create the XPath evaluator
$xpc->registerNs(x => 'http://www.w3.org/2000/svg'); # declare the namespace as x
# the query now uses x as the prefix for the svg namespace
foreach my $dead ($xpc->findnodes('//x:text')) {
print "Found Text Node\n";
$dead->unbindNode;
}
关于Perl XML/SVG 解析器无法找到节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21677123/