在一些<dt>
可能有多個<dd>
的假設下,要找到所有<dt>
然後(每個)尋找下一個<dt>
之前以下<dd>
。這在純Ruby中很容易實現,但是在XPath中做起來更有趣。 ;)
鑑於此設置:
require 'nokogiri'
html = '<dl id="first">
<dt>Label1</dt><dd>Value1</dd>
<dt>Label2</dt><dd>Value2</dd>
<dt>Label3</dt><dd>Value3a</dd><dd>Value3b</dd>
<dt>Label4</dt><dd>Value4</dd>
</dl>'
doc = Nokogiri.HTML(html)
使用沒有的XPath:
doc.css('dt').each do |dt|
dds = []
n = dt.next_element
begin
dds << n
n = n.next_element
end while n && n.name=='dd'
p [dt.text,dds.map(&:text)]
end
#=> ["Label1", ["Value1"]]
#=> ["Label2", ["Value2"]]
#=> ["Label3", ["Value3a", "Value3b"]]
#=> ["Label4", ["Value4"]]
使用小的XPath:
doc.css('dt').each do |dt|
dds = dt.xpath('following-sibling::*').chunk{ |n| n.name }.first.last
p [dt.text,dds.map(&:text)]
end
#=> ["Label1", ["Value1"]]
#=> ["Label2", ["Value2"]]
#=> ["Label3", ["Value3a", "Value3b"]]
#=> ["Label4", ["Value4"]]
使用Lotsa的XPath:
doc.css('dt').each do |dt|
ct = dt.xpath('count(following-sibling::dt)')
dds = dt.xpath("following-sibling::dd[count(following-sibling::dt)=#{ct}]")
p [dt.text,dds.map(&:text)]
end
#=> ["Label1", ["Value1"]]
#=> ["Label2", ["Value2"]]
#=> ["Label3", ["Value3a", "Value3b"]]
#=> ["Label4", ["Value4"]]
這是作品,謝謝你們! – jgiunta
而不是'doc.css('#first')。search('dt')。each'爲什麼不只是'doc.css('#first dt')。each'?還要注意,這個答案在假設在每個'
@Progrog:'.css.search'沒有什麼好的理由,但也許它更接近OP已經擁有的。而且我確實包括了「只要結構與您的示例相匹配就應該有效」的警告。我同意你的方法在一般情況下會更好。 (這只是我最後一個評論的拼寫糾正,因爲我是dun haz gud speling) –