所以我的目标是在一个范围内包装初始段落之后的所有段落。我试图弄清楚如何在单个范围内包装节点集,并且.wrap()将每个节点包装在自己的范围内。如想要:
<p>First</p>
<p>Second</p>
<p>Third</p>
成为:
<p>First</p>
<span>
<p>Second</p>
<p>Third</p>
</span>
任何示例代码都有帮助吗?谢谢!
答案 0 :(得分:1)
我会这样做:
require 'nokogiri'
doc = Nokogiri::HTML::DocumentFragment.parse(<<-html)
<p>First</p>
<p>Second</p>
<p>Third</p>
html
nodeset = doc.css("p")
new_node = Nokogiri::XML::Node.new('span',doc)
new_node << nodeset[1..-1]
nodeset.first.after(new_node)
puts doc.to_html
# >> <p>First</p><span><p>Second</p>
# >> <p>Third</p></span>
# >>
答案 1 :(得分:0)
我会这样做:
require 'nokogiri'
html = '<p>First</p>
<p>Second</p>
<p>Third</p>
'
doc = Nokogiri::HTML(html)
paragraphs = doc.search('p')[1..-1].unlink
doc.at('p').after('<span>')
doc.at('span').add_child(paragraphs)
puts doc.to_html
这导致HTML看起来像:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
<p>First</p>
<span><p>Second</p>
<p>Third</p></span>
</body></html>
为了让您知道发生了什么,这是一个更详细的输出,显示doc
的中间变化:
paragraphs = doc.search('p')[1..-1].unlink
paragraphs.to_html
# => "<p>Second</p><p>Third</p>"
doc.at('p').after('<span>')
doc.to_html
# => "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html><body>\n<p>First</p>\n<span></span>\n\n</body></html>\n"
doc.at('span').add_child(paragraphs)
doc.to_html
# => "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \"http://www.w3.org/TR/REC-html40/loose.dtd\">\n<html><body>\n<p>First</p>\n<span><p>Second</p>\n<p>Third</p></span>\n\n</body></html>\n"
查看最初的HTML,我不确定所提出的问题是否适用于普通的日常HTML,但是,如果您完全确定它永远不会改变
<p>...</p>
<p>...</p>
<p>...</p>
布局然后你应该没问题。如果HTML确实类似于:
,那么基于初始样本HTML的任何答案都会惨不忍睹<div>
<p>...</p>
<p>...</p>
<p>...</p>
</div>
...
<div>
<p>...</p>
<p>...</p>
<p>...</p>
</div>