如何选择使用引入nokogiri和XPath或CSS选择器HTML的一大块?

在我的Rails应用我有HTML一样以下,引入nokogiri解析。

我希望能够选择HTML块。 例如,我怎么能选择HTML的那部分块<sup id="21">使用XPath或CSS? 假定在实际的HTML与部分********不存在。

我想要分割由HTML <sup id=*>但问题是,该节点是兄弟姐妹。

<sup class="v" id="20"> 1 </sup> this is some random text <p></p> more random text <sup class="footnote" value='fn1'> [v] </sup> # ****************************** starting here <sup class="v" id="21"> 2 </sup> now this is a different section <p></p> how do we keep this separate <sup class="footnote" value='fn2'> [x] </sup> # ****************************** ending here <sup class="v" id="23"> 3 </sup> this is yet another different section <p></p> how do we keep this separate too <sup class="footnote" value='fn3'> [r] </sup>

--------------解决方案-------------

这里有一个简单的解决方案,让您NodeSet s的所有的节点<sup … class="v"> ,其散列id

doc = Nokogiri.HTML(your_html)

nodes_by_vsup_id = Hash.new{ |k,v| k[v]=Nokogiri::XML::NodeSet.new(doc) }
last_id = nil
doc.at('body').children.each do |n|
last_id = n['id'] if n['class']=='v'
nodes_by_vsup_id[last_id] << n
end

puts nodes_by_vsup_id['21']
#=> <sup class="v" id="21">
#=> 2
#=> </sup>
#=>
#=> now this is a different section
#=> <p></p>
#=>
#=> how do we keep this separate
#=> <sup class="footnote" value="fn2">
#=> [x]
#=> </sup>

另外,如果你真的不想要的划界“SUP”是集合的一部分,而不是这样做:

doc.at('body').elements.each do |n|
if n['class']=='v'
last_id = n['id']
else
nodes_by_vsup_id[last_id] << n
end
end

这里有一个替代方案,偶更通用的解决方案:

class Nokogiri::XML::NodeSet
# Yields each node in the set to your block
# Returns a hash keyed by whatever your block returns
# Any nodes that return nil/false are grouped with the previous valid value
def group_chunks
Hash.new{ |k,v| k[v] = self.class.new(document) }.tap do |result|
key = nil
each{ |n| result[key = yield(n) || key] << n }
end
end
end

root_items = doc.at('body').children
separated = root_items.group_chunks{ |node| node['class']=='v' && node['id'] }
puts separated['21']

它看起来像要选择之间的一切sup@id='21'sup@id='23' 使用下面的即席表达:

//sup[@id='21']|(//sup[@id='21']/following-sibling::node()[
not(self::sup[@id='23'] or preceding-sibling::sup[@id='23'])])

或者Kayessian节点集交集公式的应用:

//sup[@id='21']|(//sup[@id='21']/following-sibling::node()[
count(.|//sup[@id='23']/preceding-sibling::node())
=
count(//sup[@id='23']/preceding-sibling::node())])

require 'open-uri'
require 'nokogiri'

doc = Nokogiri::HTML(open("http://www.yoururl"))
doc.xpath('//sup[id="21"]').each do |node|
puts node.text
end

分类:Ruby on Rails的 时间:2015-03-15 人气:1
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 1.340 (s). 10 q(s)