我在名为html_data
的变量中有以下HTML,我希望用<img>
标记替换<a>
标记,并且“img”标记的src
参数变为“{”标签的href
。
现有HTML:
<!DOCTYPE html>
<html>
<head>
<title>Learning Nokogiri</title>
</head>
<body marginwidth="6">
<div valign="top">
<div class="some_class">
<div class="test">
<img src="apple.png" alt="Apple" height="42" width="42">
<div style="white-space: pre-wrap;"></div>
</div>
</div>
</div>
</body>
</html>
这是我的解决方案A:
nokogiri_html = Nokogiri::HTML(html_data)
nokogiri_html("img").each { |tag|
a_tag = Nokogiri::XML::Node.new("a", nokogiri_html)
a_tag["href"] = tag["src"]
tag.add_next_sibling(a_tag)
tag.remove()
}
puts 'nokogiri_html is', nokogiri_html
这是我的解决方案B:
nokogiri_html = Nokogiri::HTML(html_data)
nokogiri_html("img").each { |tag|
tag.name= "a";
tag.set_attribute("href" , tag["src"])
}
puts 'nokogiri_html is', nokogiri_html
虽然解决方案A工作正常,但我正在寻找使用Nokogiri更快/直接替换标签的方法。使用解决方案B,我的“img”标签确实被“a”标签取代,但“img”标签的属性仍然保留在“a”标签内。以下是解决方案B的结果:
<!DOCTYPE html>
<html>
<body>
<p>["\n", "\n", " </p>
\n", "
<title>Learning Nokogiri</title>
\n", " \n", " \n", "
<div valign='\"top\"'>
\n", "
<div class='\"some_class\"'>
\n", "
<div class='\"test\"'>
\n", " <a src="%5C%22apple.png%5C%22" alt='\"Apple\"' height='\"42\"' width='\"42\"' href="%5C%22apple.png%5C%22"></a>\n", "
<div style='\"white-space:' pre-wrap></div>
\n", "
</div>
\n", "
</div>
\n", "
</div>
\n", " \n", ""]
</body>
</html>
有没有办法使用Nokogiri在HTML中更快地替换标签?另外如何删除“\ n”s得到的结果?
答案 0 :(得分:0)
首先,请将您的样本数据(HTML)剥离到证明问题所需的最基本数量。
以下是做你想做的事情的基础:
require 'nokogiri'
doc = Nokogiri::HTML(<<EOT)
<!DOCTYPE html>
<html>
<body>
<img src="apple.png" alt="Apple" height="42" width="42">
</body>
</html>
EOT
doc.search('img').each do |img|
src, alt = %w[src alt].map{ |p| img[p] }
img.replace("<a href='#{ src }'>#{ alt }</a>")
end
doc.to_html
# => "<!DOCTYPE html>\n<html>\n <body>\n <a href=\"apple.png\">Apple</a>\n </body>\n</html>\n"
puts doc.to_html
# >> <!DOCTYPE html>
# >> <html>
# >> <body>
# >> <a href="apple.png">Apple</a>
# >> </body>
# >> </html>
这样做可以让Nokogiri干净地替换节点。
没有必要做所有这些严峻的事情:
a_tag = Nokogiri::XML::Node.new("a", nokogiri_html)
a_tag["href"] = tag["src"]
tag.add_next_sibling(a_tag)
tag.remove()
相反,创建一个字符串作为您要使用的标记,让Nokogiri将字符串转换为节点并替换旧节点:
src, alt = %w[src alt].map{ |p| img[p] }
img.replace("<a href='#{ src }'>#{ alt }</a>")
没有必要在节点之间删除无关的空白。它可以影响HTML的外观,但浏览器会吞噬那些额外的空格而不显示它。
Nokogiri可以被告知不输出节点间空白,导致压缩/乱码输出,但如何做到这一点是一个单独的问题。