我有一个包含以下内容的SVG文件:
<text x="10" y="20"
style="font-family: Helvetica;
font-size : 24;
fill : #ff0000;
stroke : #000000;">SVG text styling</text>
<text x="85" y="150"
style="font-family: Helvetica;
font-size : 24;
fill : #ff0000;
stroke : #000000;">This is the second piece of text</text>
<text x="45" y="250"
style="font-family: Helvetica;
font-size : 24;
fill : #ff0000;
stroke : #000000;">This is the third piece of text</text>
<text x="45" y="250"
style="font-family: Helvetica;
font-size : 24;
fill : #ff0000;
stroke : #000000;">test text</text>
<text x="45" y="250"
style="font-family: Helvetica;
font-size : 24;
fill : #ff0000;
stroke : #000000;">data data</text>
<text x="45" y="250"
style="font-family: Helvetica;
font-size : 24;
fill : #ff0000;
stroke : #000000;">txt txt txt</text>
我想从中获取一些数据。我使用Nokogiri::Slop
:
@test = Nokogiri::Slop(File.open("./file.svg"))
和这个ERb:
<% @test.xpath('//text').map do |i|%>
<%=i%>
<% end %>
这样可行,但我现在的问题是如何让孩子font-family,font-size,fill,stroke
我试过这段代码
<%=i.("[@stroke]").text.content %>
但它不起作用。
答案 0 :(得分:2)
为了在ERB中使用数据,您应该首先将其转换为控制器中更友好的内容。此代码将生成一个哈希数组,您可以在视图中分开:
require 'nokogiri'
doc = Nokogiri::XML(<<EOT)
<svg>
<text x="10" y="20"
style="font-family: Helvetica;
font-size : 24;
fill : #ff0000;
stroke : #000000;">SVG text styling</text>
<text x="85" y="150"
style="font-family: Helvetica;
font-size : 24;
fill : #ff0000;
stroke : #000000;">This is the second piece of text</text>
<text x="45" y="250"
style="font-family: Helvetica;
font-size : 24;
fill : #ff0000;
stroke : #000000;">This is the third piece of text</text>
<text x="45" y="250"
style="font-family: Helvetica;
font-size : 24;
fill : #ff0000;
stroke : #000000;">test text</text>
<text x="45" y="250"
style="font-family: Helvetica;
font-size : 24;
fill : #ff0000;
stroke : #000000;">data data</text>
<text x="45" y="250"
style="font-family: Helvetica;
font-size : 24;
fill : #ff0000;
stroke : #000000;">txt txt txt</text>
</svg>
EOT
此时Nokogiri有一个XML文档。
以下是走<text>
个节点所需的全部内容:
text_styles = doc.search('text').map { |text|
Hash[text['style'].split(';').map{ |attr| attr.split(':').map(&:strip) }]
}
运行时,将返回包含以下内容的text_styles
text_styles
# => [{"font-family"=>"Helvetica",
# "font-size"=>"24",
# "fill"=>"#ff0000",
# "stroke"=>"#000000"},
# {"font-family"=>"Helvetica",
# "font-size"=>"24",
# "fill"=>"#ff0000",
# "stroke"=>"#000000"},
# {"font-family"=>"Helvetica",
# "font-size"=>"24",
# "fill"=>"#ff0000",
# "stroke"=>"#000000"},
# {"font-family"=>"Helvetica",
# "font-size"=>"24",
# "fill"=>"#ff0000",
# "stroke"=>"#000000"},
# {"font-family"=>"Helvetica",
# "font-size"=>"24",
# "fill"=>"#ff0000",
# "stroke"=>"#000000"},
# {"font-family"=>"Helvetica",
# "font-size"=>"24",
# "fill"=>"#ff0000",
# "stroke"=>"#000000"}]
代码读取数据并将其解析为XML。然后,使用search
查找CSS选择器text
。为何选择CSS?它更容易阅读。
找到<text>
节点后,它会从节点中检索style
属性,然后在;
上拆分它的值,然后,对于每个生成的数组,它将它们拆分为:
并删除前导/尾随空格。
最后,它将生成的数组数组转换为哈希值并返回它。
答案 1 :(得分:0)
您的XML中的font-family
,font-size
,fill
和stroke
项是不是 XML属性,因此您无法获取它们(直接与Nokogiri。它们是字符串的一部分,该字符串是style
属性的值。您将不得不获取该字符串,然后以某种方式在Ruby中解析它。
以下是一个示例,说明如何为第一个text
元素获取这四个值的值:
# first get the complete string:
styles = @test.at_xpath("//text/@style").value
# next split the string into key values pairs on ;, then each pair
# into spearate strings on :, and create a hash with the result
style_hash = Hash[style1.split(/\s*;\s*/).map { |s| s.split(/\s*:\s*/)}]