使用Ruby删除XML文档中的所有标记

时间:2011-04-27 15:38:30

标签: ruby xml nokogiri

require 'nokogiri'

doc = Nokogiri::XML "<root>
    <a>foo<c>bar</c></a>
  <b>jim<d>jam></d></b>
  <a>more</a>
  <x>no no no</x>
</root>"

doc.css("a, b").each {|o| p o.to_s}
# "<a>foo<c>bar</c></a>"
# "<a>more</a>"
# "<b>jim<d>jam&gt;</d></b>"

如何按原始顺序保留标签?或者还删除嵌套标签?

3 个答案:

答案 0 :(得分:1)

您可能需要查看白名单/黑名单/清理宝石。我会想到SanitizeLoofah

来自Sanitize的描述:

  

给定一个可接受的元素和属性列表,Sanitize将从字符串中删除所有不可接受的HTML。

来自Loofah的描述:

  

Loofah擅长HTML清理(XSS预防)。它包含一些很好的HTML清理程序,它们基于HTML5lib的白名单,因此很可能不会使您的代码安全性降低。 (这些陈述尚未经过Netexperts评估。)

在任何一种情况下,它们都会让你免于重新发明轮子。

答案 1 :(得分:0)

如果这只是一个订单问题而且你需要隔离的标签都没有嵌套,那么在Nokogiri中使用XPath而不是CSS选择器应该按照它们在文档中的顺序返回标签:

doc.xpath("//a | //h3").each { |o| puts o }

我不确定这种行为是否符合Nokogiri的任何规范,所以你可能要小心,但根据我的经验,这是真的。

当然,如果您所使用的标签曾经嵌套过,您可能需要定义“除去某些标签之外的所有标签”的含义(例如,移除的标签及其内容存在于非移除标签内部和他们的内容等。)。

如果您的要求非常复杂,以至于XPath查询不会削减它,您可能需要使用类似doc.root.children的东西“遍历DOM”并递归检查每个节点的子节点。

答案 2 :(得分:0)

require 'nokogiri'
doc = Nokogiri::XML "
<root>
  <a>foo<c>bar</c></a>
  <b>jim<d>jam></d></b>
  <a>more</a>
  <x>no no no</x>
</root>"

doc.xpath('root//*[name()!="a"][name()!="b"]').remove
puts doc
#=> <?xml version="1.0"?>
#=> <root>
#=>   <a>foo</a>
#=>   <b>jim</b>
#=>   <a>more</a>
#=>   
#=> </root>