html - 使用 Nokogiri 替换标签 - 更快的方法?

标签 html css ruby nokogiri

我在名为 html_data 的变量中有以下 HTML我想替换 <img> 的地方带有 <a> 的标签标签和 src “img”标签的参数变为 href “a”标签。

现有的 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”?

最佳答案

首先,请将您的示例数据 (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 可以被告知不要输出节点间的空白,从而导致压缩/错误的输出,但如何做到这一点是一个单独的问题。

关于html - 使用 Nokogiri 替换标签 - 更快的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29656223/

相关文章:

html - 为什么float和div之间有间隙?

javascript - 使用 Knockout 设置更改事件进入选择下拉列表

具有自动多列显示内容的 Javascript CSS

html - CSS 命名网格碎片化,同名区域未连接

html - 在 div 中调整图片大小和对齐图片

ruby-on-rails - Rails 3.1 中的未定义方法 `relationships_path'

ruby - 我如何优化这段 ruby​​ 代码以使其运行得更快?

ruby - Redis:如何在 ruby​​ 客户端中以编程方式加载 dump.rdb

javascript - 刷新后需要一个事件的子菜单(jquery Accordion 菜单)

javascript - 垂直动画图像 - jQuery