0

任何熟悉 RubyGem Sanitize 的人,都提供了构建“Transformer”以进行转换的示例

"<ul><li>a</li><li>b</li><li>c</li></ul>" 

进入

"a,b, and c"

?

4

1 回答 1

1

IMO 转换器不适用于提取这样的数据:

Transformer 允许您使用自己的自定义逻辑过滤和修改节点 [...]

这不是你想要做的;您正在尝试从节点中提取数据并对其进行转换。在您的示例中,您对每个元素都没有做同样的事情:您有时会附加一个逗号,有时会附加一个逗号和单词“and”。

为此,您要么需要保存状态和后期处理,要么在节点流中向前看,看看您是否正在访问最后一个节点。我不知道用 Sanitize 的转换器来做这件事的简单方法,所以这个例子保存了状态和后期处理。

require 'sanitize'
items = []
s = "<ul><li>some space</li><li>more stuff with spaces</li><li>last one</li></ul>"
save_li = lambda do |env|
  node = env[:node]
  items << node.text.strip if node.text?
end
Sanitize.clean(s, :transformers => save_li)
# => "  some space  more stuff with spaces  last one  "    
output = "#{items[0..-2].join(", ")}, and #{items[-1]}"
# => "some space, more stuff with spaces, and last one"

IMO 这个例子是对转换器的滥用,因为它只是为了它的副作用而运行,它除了寻找文本节点之外什么都不做。

如果其中一个列表项嵌入了 HTML,那么幼稚的方法将不再有效,并且无论如何您都需要开始了解更多 Nokogiri:

items = []
s = "<ul><li>some space</li><li>item <b>with<b/> html</li><li>c</li></ul>"
save_li = lambda do |env|
  node = env[:node]
  items << node.content if node.name == "li"
end
Sanitize.clean(s, :transformers => save_li)
# => "  some space  item with html  c  "
output = "#{items[0..-2].join(", ")}, and #{items[-1]}"    
# => "some space, item with html, and c"

这种方法依赖于没有被列入白名单的默认 Sanitize 行为。<b>lambda仍会访问这些标签save_li,但它们已被剥离。这有可能在各种情况下引起问题。

于 2011-12-24T15:50:55.543 回答