0

変換する「トランスフォーマー」を作成する例を提供する RubyGem Sanitize に精通している人

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

の中へ

"a,b, and c"

?

4

1 に答える 1

1

IMO トランスフォーマーは、次のようなデータを引き出すためのものではありません。

トランスフォーマーを使用すると、独自のカスタム ロジックを使用してノードをフィルター処理および変更できます [...]

これはあなたがやろうとしていることではありません。ノードからデータを引き出して変換しようとしています。あなたの例では、各要素に同じことをしていません.コンマを追加することもあれば、コンマと「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 この例は、副作用のためだけに実行されているため、トランスフォーマーの悪用です。テキスト ノードを探す以外には何もしません。

リスト アイテムの 1 つに HTML が埋め込まれている場合、素朴なアプローチは機能しなくなります。

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"

このアプローチは、何もホワイトリストに登録されていないというデフォルトのサニタイズ動作に依存しています。<b>タグは引き続きラムダによってアクセスされますが、save_li取り除かれます。これは、さまざまな状況で問題を引き起こす可能性があります。

于 2011-12-24T15:50:55.543 に答える