Исходя из того, как структурирован ваш HTML, вы должны начать:
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div>
<div>
<div>
<p>Some text</p>
</div>
</div>
</div>
</body>
</html>
EOT
dd = doc.at('div div').parent
dp = dd.at('div p')
dd.children.unlink
dp.parent = dd
В результате:
puts doc.to_html
# >> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
# >> <html>
# >> <head>
# >> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
# >> </head>
# >> <body>
# >> <div><p>Some text</p></div>
# >> </body>
# >> </html>
dd
- это parent
для двух последовательных тегов div
, другими словами, это первый div
в цепочке.
dp
- это узел p
в конце этой цепочки.
dd.children
- это NodeSet, содержащий children
из dd
, вплоть до, включая dp
.
Идея состоит в том, чтобы привить dp
, (требуемый узел <p>
), до dd
, (самый верхний узел <div>
), после удаления всех других промежуточных тегов <div>
. NodeSet позволяет легко unlink
большого количества тегов одновременно.
Прочитайте о at
, чтобы понять, почему это важно для такого рода проблем.