我正在做的事情是需要获取SVG
文件中各个路径的路径数据,以便生成相似的路径。
在惊恐地处理了用于处理SVG文件的大量c / c ++库之后,我决定将perl(因为它更适合对SVG路径数据的香肠进行分类的工作)与XML解析器一起使用。出于某种原因,我选择了XML::Easy
(我有一个很好的理由。那是昨天,我不记得它是什么了。可能是应该是Easy
的事实)作为解析器。>
但是,除了perldoc和metacpan之外,我没有找到其他任何教程或文档。
我设法使用XML::Easy::Element
将文件读入xml10_read_document
引用中,但是我不知道如何获取实际路径数据。
如何从XML::Easy::Element
参考获得路径香肠?
编辑:我指的香肠是路径中的d属性。 EG:来自
<svg>
[...]
<g id=something>
<path d="M350.41,62.567v0.135l1.118,0.04v-0.135L350.41,62.567z
M351.898,60.655c-0.242,0-0.433,0.059-0.572,0.175c-0.089,0.104-0.179,0.207-0.269,0.311l-0.014-0.445l-0.875-0.013v0.31
l0.458,0.067l-0.041,1.421l0.498,0.006l0.014-0.754c0.197-0.449,0.438-0.673,0.72-0.673c0.193,0,0.29,0.11,0.29,0.329
c0,0.108-0.025,0.223-0.074,0.344l0.316,0.081c0.085-0.148,0.128-0.312,0.128-0.491c0-0.185-0.047-0.34-0.142-0.465
C352.228,60.723,352.082,60.655,351.898,60.655z
M350.572,62.816l-0.027,0.922l0.525-0.08l0.006-0.835L350.572,62.816z"/>
</g>
[...]
</svg>
我想提取
"M350.41,62.567v0.135l1.118,0.04v-0.135L350.41,62.567z
M351.898,60.655c-0.242,0-0.433,0.059-0.572,0.175c-0.089,0.104-0.179,0.207-0.269,0.311l-0.014-0.445l-0.875-0.013v0.31
l0.458,0.067l-0.041,1.421l0.498,0.006l0.014-0.754c0.197-0.449,0.438-0.673,0.72-0.673c0.193,0,0.29,0.11,0.29,0.329 c0,0.108-0.025,0.223-0.074,0.344l0.316,0.081c0.085-0.148,0.128-0.312,0.128-0.491c0-0.185-0.047-0.34-0.142-0.465
C352.228,60.723,352.082,60.655,351.898,60.655z
M350.572,62.816l-0.027,0.922l0.525-0.08l0.006-0.835L350.572,62.816z"
答案 0 :(得分:3)
下面是我如何与做Mojo::DOM:
use strict;
use warnings;
use Mojo::DOM;
my $svg = <<'SVG';
<svg>
[...]
<g id="something">
<path d="M350.41,62.567v0.135l1.118,0.04v-0.135L350.41,62.567z
M351.898,60.655c-0.242,0-0.433,0.059-0.572,0.175c-0.089,0.104-0.179,0.207-0.269,0.311l-0.014-0.445l-0.875-0.013v0.31
l0.458,0.067l-0.041,1.421l0.498,0.006l0.014-0.754c0.197-0.449,0.438-0.673,0.72-0.673c0.193,0,0.29,0.11,0.29,0.329
c0,0.108-0.025,0.223-0.074,0.344l0.316,0.081c0.085-0.148,0.128-0.312,0.128-0.491c0-0.185-0.047-0.34-0.142-0.465
C352.228,60.723,352.082,60.655,351.898,60.655z
M350.572,62.816l-0.027,0.922l0.525-0.08l0.006-0.835L350.572,62.816z"/>
</g>
[...]
</svg>
SVG
my $dom = Mojo::DOM->new->xml(1)->parse($svg);
my $sausage = $dom->at('path')->{d};
或者如果您想从特定的<g>
标记而不是第一个标记中获取它,
my $sausage = $dom->at('g#something path')->{d};
答案 1 :(得分:2)
在深入研究XML :: Easy的文档之后,我认为这会起作用:
use strict;
use warnings;
use XML::Easy::Text 'xml10_read_document';
use XML::Easy::NodeBasics qw(xml_e_content_twine xml_e_type_name xml_e_attribute);
use List::Util 'first';
my $svg = <<'SVG';
<svg>
[...]
<g id="something">
<path d="M350.41,62.567v0.135l1.118,0.04v-0.135L350.41,62.567z
M351.898,60.655c-0.242,0-0.433,0.059-0.572,0.175c-0.089,0.104-0.179,0.207-0.269,0.311l-0.014-0.445l-0.875-0.013v0.31
l0.458,0.067l-0.041,1.421l0.498,0.006l0.014-0.754c0.197-0.449,0.438-0.673,0.72-0.673c0.193,0,0.29,0.11,0.29,0.329
c0,0.108-0.025,0.223-0.074,0.344l0.316,0.081c0.085-0.148,0.128-0.312,0.128-0.491c0-0.185-0.047-0.34-0.142-0.465
C352.228,60.723,352.082,60.655,351.898,60.655z
M350.572,62.816l-0.027,0.922l0.525-0.08l0.006-0.835L350.572,62.816z"/>
</g>
[...]
</svg>
SVG
my $root = xml10_read_document($svg);
my $contents = xml_e_content_twine($root);
my $g = first { ref $_ and xml_e_type_name($_) eq 'g' and xml_e_attribute($_, 'id') eq 'something' } @$contents;
my $g_contents = xml_e_content_twine($g);
my $path = first { ref $_ and xml_e_type_name($_) eq 'path' } @$g_contents;
my $sausage = xml_e_attribute($path, 'd');
对我来说似乎很难。我建议改用任何XPath或CSS解析器。
答案 2 :(得分:0)
由于您不记得选择使用XML::Easy
的原因,因此请考虑使用XML::Simple::):
use XML::Simple qw( XMLin ) ;
my $svg = q{
<svg width="190" height="160" xmlns="http://www.w3.org/2000/svg">
<path d="M10 10 C 20 20, 40 20, 50 10" stroke="black" fill="transparent"/>
<path d="M70 10 C 70 20, 120 20, 120 10" stroke="black" fill="transparent"/>
<path d="M70 10 C 70 20, 120 20, 120 10" stroke="black" fill="transparent"/>
</svg>
};
my $decoded = XMLin( $svg, ForceArray => 1 ) ;
foreach my $path ( @{ $decoded->{ path } } ){
my $data = $path->{d} ;
my $stroke = $path->{stroke} ;
my $fill = $path->{ fill } ;
...
}
$decoded->{ path }
在哪里:
[
{
d => "M10 10 C 20 20, 40 20, 50 10",
fill => "transparent",
stroke => "black"
},
{
d => "M70 10 C 70 20, 120 20, 120 10",
fill => "transparent",
stroke => "black"
},
{
d => "M70 10 C 70 20, 120 20, 120 10",
fill => "transparent",
stroke => "black"
}
]
注意:正如格林尼茨所指出的,不要将XML::Simple
用于比平凡的SVG更复杂的事情。