なんでこんな基本機能知らなかったのかという感じですが、Rubyで文字列をXMLエスケープする際、
"abc<tag>def".encode(xml: :text)
でいけます。
いちいちCGIモジュールを使わなくて良いので気軽ですね。
おまけ
ついでなのでencode
メソッドに指定できるオプションでも。
undef: :replace
変換先のエンコーディングに対応文字がないとき、通常はEncoding::UndefinedConversionError
が発生しますが、これを「?」などに置換します。
str = '鷗'
str.encode 'Shift_JIS'
#=> Encoding::UndefinedConversionError: U+9DD7 from UTF-8 to Shift_JIS
str.encode 'Shift_JIS', undef: :replace
#=> "?"
invalid: :replace
変換元の文字列に、変換元エンコーディングとして不正なバイト列があるとき、通常はEncoding::InvalidByteSequenceError
が発生しますが、これをU+FFFD(REPLACEMENT CHARACTER)などに置換します。
str = '鷗'
str.force_encoding 'Shift_JIS'
str.encode 'UTF-8'
#=> Encoding::InvalidByteSequenceError: incomplete "\x97" on Shift_JIS
str.encode 'UTF-8', invalid: :replace
#=> "鮃�"
# replaceする文字は指定できる
str.encode 'UTF-8', invalid: :replace, replace: '?'
#=> "鮃?"
なお、�はでたらめな文字化け結果ではなくて、「そんな文字無いから置き換えたよ」という立派な意味を持つU+FFFD(REPLACEMENT CHARACTER)なのでかわいがってあげましょう。