Ruby/RailsでXML中の不正な制御文字を削除する

スポンサーリンク

Rails で ActiveRecord と ActionView::Helpers::AtomFeedHelper を使って、データベースの中身からデータを引っ張って Atom フィードを出力するコードを書いていたら問題発生。DBから引っ張ってきたデータ中に制御文字が含まれていて、出力された Atom フィードの CDATA セクションにその制御文字が入り込み、XML 書式が不正なものとなってしまいました。

— 環境 —
Rails 4.1

【お知らせ】 英単語を画像イメージで楽に暗記できる辞書サイトを作りました。英語学習中の方は、ぜひご利用ください!
画像付き英語辞書 Imagict | 英単語をイメージで暗記
【開発記録】
英単語を画像イメージで暗記できる英語辞書サービスを作って公開しました
スポンサーリンク

XML1.0 で不正になる制御文字

ということでまずは、XML 中で invalid となる文字について XML の仕様書(RFC)に当たって調べました。

The characters to be escaped are the control characters #x0 to #x1F and #x7F (most of which cannot appear in XML), space #x20, the delimiters ‘<' #x3C, '>‘ #x3E and ‘”‘ #x22, the unwise characters ‘{‘ #x7B, ‘}’ #x7D, ‘|’ #x7C, ‘\’ #x5C, ‘^’ #x5E and ‘`’ #x60, as well as all characters above #x7F.

上記 W3C のページは、「Note: On 7 February 2013, this specification was modified in place to replace broken links to RFC4646 and RFC4647.」とあるので、リンクが壊れた RFC4646, 4647 の内容の代わりに設置された XML1.0 の仕様だろうと思われます。

引用した部分に XML 中でエスケープすべき制御文字コードがずらずらっと書いてある。

制御コード表

以下のエントリーなども参考になりました。

XML1.0にvalidな文字列の出力 – memo.mzt
PHPでのXMLパースエラー出力は必須だね – 今からお前んちこいよ

PHP で simplexml_load_string() を使って RSS フィードをパースすると、RSS フィードに制御文字が入っていた場合エラーになるらしい。困ったもんだ…

text.gsub(/[[:cntrl:]]/, ”) で対応

stackoverflow の以下ページ等を参考にして対処しました。

Ruby regex remove ^C character from string – Stack Overflow
Invalid Characters in XML – Stack Overflow

少々乱暴なやり方っぽくも感じるけど、出力の際に Ruby の String#gsub メソッドを使って、正規表現指定で制御文字を全部空文字に置換する方法をとりあえず試してみた。

views/users/posts.atom.builder

これで一応出力される Atom フィードの XML が valid なものとなり、上手く動作しました。このやり方で問題が出たら、また対処しようと思います。最後に Rails で RSS/Atom フィードを作成する方法については以下参考。

RailsでAtomフィードを生成 | EasyRamble
RailsでRSSフィードを生成 | EasyRamble

スポンサーリンク
パーフェクト Ruby on Rails は、最近読んだ Rails 本の中では一番役に立った本です。Chef や Capistrano など Rails と共によく使用される技術にも触れてあります。Ruby on Rails 4 アプリケーションプログラミングは、入門的な内容で Rails の機能全体を網羅されています。
 
スポンサーリンク

Leave Your Message!