我試圖解析一個xml看起來像這樣:引入nokogiri:趿拉訪問節點名爲name
<lesson>
<name>toto</name>
<version>42</version>
</lesson>
使用Nokogiri::Slop
。
我可以通過lesson.version
輕鬆訪問課程,但無法訪問lesson.name
,因爲名稱在本例中指的是節點(課程)的名稱。
有什麼方法可以訪問孩子嗎?
我試圖解析一個xml看起來像這樣:引入nokogiri:趿拉訪問節點名爲name
<lesson>
<name>toto</name>
<version>42</version>
</lesson>
使用Nokogiri::Slop
。
我可以通過lesson.version
輕鬆訪問課程,但無法訪問lesson.name
,因爲名稱在本例中指的是節點(課程)的名稱。
有什麼方法可以訪問孩子嗎?
您可以使用search
並給予節點的XPath或CSS選擇器:
doc.lesson.search('name').first
做使用元編程有點破解。
require 'nokogiri'
doc = Nokogiri::Slop <<-HTML
<lesson>
<name>toto</name>
<version>42</version>
</lesson>
HTML
name_val = doc.lesson.instance_eval do
self.class.send :undef_method, :name
self.name
end.text
p name_val # => toto
p doc.lesson.version.text # => '42'
Nokogiri::XML::Node#name
被定義爲獲得Nokogiri::XML::Node
名稱的方法。只需一段時間,從#instance_eval
範圍內的類Nokogiri::XML::Node
中刪除該方法。
我喜歡它,並且在這種情況下會更好,但是,在這種特定情況下,我更喜歡單行:) – Antzi
作爲一個變體,你可以試試這個:
doc.lesson.elements.select{|el| el.name == "name"}
爲什麼?正因爲如此基準:
require 'nokogiri'
require 'benchmark'
str = '<lesson>
<name>toto</name>
<version>42</version>
</lesson>'
doc = Nokogiri::Slop(str)
n = 50000
Benchmark.bm do |x|
x.report("select") { n.times do; doc.lesson.elements.select{|el| el.name == "name"}; end }
x.report("search") { n.times do; doc.lesson.search('name'); end }
end
這給我們的結果:
#=> user system total real
#=> select 1.466000 0.047000 1.513000 ( 1.528153)
#=> search 2.637000 0.125000 2.762000 ( 2.777278)
也可以加我..讓我看看meta編程的*缺點* ..: - ) –
缺點是'el.name'不起作用,強制轉換''method_missing':未定義的方法'name'爲#
什麼?我的代碼拋出錯誤? :-(我沒有... –
號。問題是關於'Slop'。 –
它仍然與普通的選擇器混合在一起。 – hakcho
是的。但我正在關注* Slop裝飾器實現了method_missing,因此可以使用方法而不是CSS或XPath。* :-)沒問題,你是對的。 –