BLOGTIMES
2010/11/29

UTF-8のBOMの削除でハマる

  java  ruby  charset  regex 
このエントリーをはてなブックマークに追加

XalanでXMLをXSL変換するプログラムを書いたら、そのうちの1つのXMLが下記のエラーを吐いて変換できなくてハマってしまいました。

Caused by: javax.xml.transform.TransformerException: com.sun.org.apache.xml.internal.utils.WrappedRuntimeException: An invalid XML character (Unicode: 0xfffe) was found in the element content of the document.

エラーから分かることはドキュメントに0xFFFEが含まれているということ。この文字はBOM(0xFEFF)のエンディアンを間違えたときの文字列なので確かにXMLに使うことはできません。エディタで開くと一見間違いはないように見えますが、Firefoxで表示させようとすると「XML パースエラー: 整形式になっていません。」と他の処理系でもエラーを吐きます。

元になったXMLはRubyのプログラムから生成したものだったので、元になったStringから下記のように BOM を削除するルーチンを埋め込んでみました。

str = str.gsub(/\xFE\xFF|\xFF\xFE/,"")

上記を利用してXMLを再生成してみたのですが、依然としてエラーは消えません。ここでしばらくハマっていましたが、XalanはJavaなので0xFFFEはUTF-16の表現であることを見落としていることに気づきました。今回のXMLはUTF-8だったので、BOMのUTF-8表現を「日本語文字コード変換 mojimoji」で調べて正規表現を書き直したところ、これがビンゴでした。

UTF-16 UTF-8 BOM 0xFEFF → 0xEFBBBF BOMの反転 0xFFFE → 0xEFBFBE
str = str.gsub(/\xEF\xBB\xBF|\xEF\xBF\xBE/,"")

元のStringにBOMが混入していた原因は不明。本当に文字コードはくだらないところでハマりますね。


    トラックバックについて
    Trackback URL:
    お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
    このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/3930
    Trackbacks
    このエントリにトラックバックはありません
    Comments
    愛のあるツッコミをお気軽にどうぞ。[policy]
    古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
    コメントはありません
    Comments Form

    コメントは承認後の表示となります。
    OpenIDでログインすると、即時に公開されます。

    OpenID を使ってログインすることができます。

    Identity URL: Yahoo! JAPAN IDでログイン