プロが教えるわが家の防犯対策術!

 以前からずっと疑問だったのですが。。。
 XML宣言の中に、エンコーディングを記述するところがありますが、その宣言文字列自体をそのエンコーディングで記述するというのはおかしくないでしょうか。
 たとえば、UTF-16だったら、

encoding="UTF-16"

と書くわけですが、これ自体がUTF-16で書かれているわけですよね? UTF-16で書かれているとわかっていたら宣言する必要はないし、宣言読まないとわからないんだったら、この宣言自体も読めないはずです。
 今実際に、UTF-16で書かれていて、エンコーディング宣言もしているXML文書をあるソフトで読もうとしているのですが、1バイト目を読んだところで「Unexpected character. position = 0 」と出力されてエラーになります。
 強制的にUTF-16で読ませる昨日もあるので、そうすればエラーは起こりませんが、それじゃエンコーディング宣言の存在自体に意味がないのでは? これは、最初の時点で読めないこと自体がこのソフトの不具合なのでしょうか?
 これってどういうことなんでしょう。解決できるんでしょうか。

A 回答 (7件)

参考書の受け売りでスイマセン。

O'Reilly から出ている "XML in a nutshell" というリファレンス本に、XML パーサのエンコーディング想定処理についての記述がありました。以下、拙訳ですが、当該部分の引用です。
-- * -- * --
(略) XML パーサは、文書の最初の数バイトからその文字セットの想定を試みるだろう。パーサによる基本的なチェックは以下の処理を含む:

・もし最初の2バイトが #xFEFF の場合、パーサはそのバイト列をユニコードのバイトオーダーマーク(BOM)と認識するであろう。そして、その文章はビッグエンディアンのユニコードの UCS-2 (訳注; UTF-16)で記述されていると想定される。その知識に基づいて、残りの文章を読み進める。

・もし最初の2バイトが #xFFFE の場合、パーサはそのバイト列をユニコードのバイトオーダーマーク(BOM)と認識するであろう。そして、その文章はリトルエンディアンのユニコードの UCS-2 (訳注; UTF-16)で記述されていると想定される。その知識に基づいて、残りの文章を読み進める。

・もし最初の4バイトが #x3C3F786D の場合、つまりこれは ASCII 文字の "<?xml" だが、その場合そのファイルは ASCII 文字の上位セットで記述されていると想定される。特にユニコードの UTF-8 で記述されていると仮定するかもしれない。仮にそれが間違いだったとしても、この情報は、どの文字セットを実際に使っているかの宣言に辿り着く迄は、残りの文章を読み進める上では十分と言えよう。
-- * -- * --

他にも、XML パーサは UTF-8 と UTF-16 には対応していなければならないような記述もありますので、上記のような UTF-16 を前提とした処理も必要なのではないでしょうか。

参考URL:http://www.oreilly.com/catalog/xmlnut3/

この回答への補足

あ、訳までして頂いたんですね!
本当に本当にありがとうございました。とても役に立ちました。<(_ _)>

補足日時:2005/09/22 14:54
    • good
    • 0
この回答へのお礼

ありがとうございました。
つまり、xmlというのは、

・UTF-16
・ASCIIの上位文字セット

だけでしか記述できないという仕様である、というわけですね。やはり、基本的には「汎用機の文字セットなどではXMLは記述できない」となりますね。少なくとも規格としてはサポートできない。FEFFなどを文字として扱う処理系があったらもうダメですからね。
そして、「encoding=」で記述するのは、ASCIIの上位セットの判別のためだけ、ということになるんでしょうか。つまり、UTF-16で書いている場合には、最初の2バイトで判別しているので、「encoding=」で指定しても意味がない、ということになるわけですからね。
それでしたら納得です。やっぱり「encoding='UTF-16'」は意味がないみたいですね。ダブルチェックのためくらいには使えるかもしれないですけど、それを読んで判別しているわけではないのですね。

どうもありがとうございました。長年の謎が(釈然とはしないながらも)理解できました。

お礼日時:2005/09/22 14:48

> そのXMLのエンコーディングが「必ずasciiで記述されている」別のファイルを用意するような仕様にするとか



うーん、それだったら最初から「XML は UTF-8/16 でしか書いてはいけない」って決めちゃったほうが楽ですよね。実際、仕様策定者たちも本音としてはそうしたかったんじゃないでしょうか。
でもさすがに UTF-8/16 だけっていうわけには行かないから、「UTF-8/16 は必ず対応し、他のエンコーディングは各プロセッサが任意に対応する」という仕様に落ち着いたと。
    • good
    • 0

>と思ったのですが、考えてみたらエンコーディングを指定して


>読ませれば読めるので、先頭のバイトオーダーマークについて
>はきちんと解釈しているようです。

憶測のみで申し訳ありませんが、そうとも限りません。
「エンコーディングを指定された時は、指定のフォーマットでのデコードを試み、デコードされた文字のみ読み込む」と言う処理をする筈です。

ですので「先頭のバイトオーダーマークを無視して読み込んでいる」と言う可能性があります。

たぶん、該当ソフトは「リトルエディアンとビックエディアンの両方でコード変換を試してみて、上手く行った方で、リトルかビックかエディアンを決めている」と言う事をしているのでしょう。

で、ファイルの先頭のバイトオーダーマークは ff fe と fe ff の片方だけを正常と判定し、もう片方をエラーにしちゃってる可能性が高いです。

つまり「バイトオーダーマーク」を「UTF-16ファイル固有の固定のマーク」と勘違いしちゃってる、のではないかと。
    • good
    • 0

ちょっと補足です。

XMLパーサは、ASCIIの上位セットとUTF-16は対応する必要がありそうですが、それ以外の文字セットに対応していけないワケではなく、先ほどの例のように文字セット毎の判定処理が必要になる、というだけかと思ってます。

件の本でも「(例えば)EBCDIC や UCS-4 を理解できるパーサは、同様のヒューリスティックなエンコーディング判定処理が必要になる」という記述があります。

いずれにせよ、annyGrace さんの疑問についてはパーサにて UTF-16 を想定した BOM 周辺処理(実際は BOM がない場合でも UTF-16 かどうか判定可能でないとまずそうですが)が必要ではないかと思います。
    • good
    • 0

まあたしかに、おっしゃるとおりですね。


UTF-8 や Shift_JIS のように ASCII と互換性のあるエンコーディングなら XML 宣言を見てから判断するということもできますが、UTF-16 だとそういうわけには行きませんね。

UTF-16 であることを示す記述を UTF-16 でエンコードした状態で読み込ませても意味がないというのはもっともですが、これは UTF-16 に限らずどのエンコーディングを使った場合にも言えることで、それは XML 文書がもともとテキストファイルである以上どうしようもないことです。

ただ、エンコーディングを判別するための手がかりとしては、XML 宣言は決して無駄ではないと思います。とりあえず XML 宣言の部分だけでも読み込めれば後は何とかなるんですから。

ところで、ソフトで読み込めないのはたぶんそのソフトに不具合があるか、ソフトのエンコーディング判別機能があまり賢くないからだと思います。

この回答への補足

むー、そうでしょうか。
たとえば僕だったら、そのXMLのエンコーディングが「必ずasciiで記述されている」別のファイルを用意するような仕様にするとか、まあそんなカンジにするんじゃないかと思います。今でもXMLはそれ単体で機能することはまれで、DTDやらXMLスキーマなんかの別のファイルを必要とするんですから。
いずれにせよ、目的地までの地図を、その目的地だけでしか配ってないような、こんな**な仕様がなんで平然とまかり通っているのか不思議でなりません。KEISとかJEFとかでXMLって書けるのだろうか。

補足日時:2005/09/22 13:13
    • good
    • 0

宣言自体が何で書かれているにせよ「宣言がある」と言うのが重要です。



例えば「『あいうえお』をUTF-16にエンコードしたバイト列」と「画像データの先頭数バイト」が偶然に一致してしまった場合を考えて下さい。

もし「宣言」が無ければ「UTF-16にエンコードしたバイト列」なのか「画像データの先頭数バイト」なのか、判断する事が出来ません。なぜなら、どちらも「あいうえお」を示す文字列と同じデータ列な訳ですから。

その為、宣言自体が何で書かれているにせよ「宣言されている事が重要」なのです。

それと、最初の1バイト目を読んでエラーになるソフトの件ですが、たぶん、ソフト側の不具合です。

UTF-16のエンコードでは「16ビットデータのバイト並び」がリトルエディアンとビックエディアンの2種類あります(上位バイトと下位バイトのどちらが先に来るか、で2種)

そこで、データがリトルエディアンなのかビックエディアンなのか判断する為、ファイルの先頭1バイトに「バイトオーダーマーク」を入れて、エディアンがどちらか判断出来るようになっています。

あくまで予想ですが、不具合が出ているソフトは「先頭にバイトオーダーマークがあった時の事」を考慮していないのでしょう。

このソフトがエラーを起こすのは「宣言の有無」は無関係で、単純に「2つある形式のうち、1つの形式でしか読めない。もう1つの形式をサポートしてない。つまり、ソフト開発者がUTF-16を良く判ってない」だけなのでしょう。

ソフトの開発元に「UTF-16のリトルエディアンとビックエディアンのうち片方しか読めない不具合がある。両方のUTF-16を読めるように修正してくれ」と不具合報告、修正要望を出してみては如何でしょう?

この回答への補足

と思ったのですが、考えてみたらエンコーディングを指定して読ませれば読めるので、先頭のバイトオーダーマークについてはきちんと解釈しているようです。
やはり「UTF-16で書かれている」ということ自体を認識できないのではないかという気がしてきました。

補足日時:2005/09/22 13:31
    • good
    • 0
この回答へのお礼

うーん、どうなんでしょう。
「偶然一致する可能性」という話であれば、「encoding='UTF16'」という文字列と「偶然一致する可能性」もありますから。可能性が高いからダメ、低いからOK、なんて、まあ大学生が作ってるフリーウェアの仕様であればまだしも、国際的な標準化団体の規格として策定してしまっていいものかという気はしますが。

ただ、UTF-16の先頭のエンディアン判別記号の問題については了解しました。どうやらそうみたいですね。おっしゃるとおりにしてみたいと思います。ありがとうございました。

お礼日時:2005/09/22 13:10

>これ自体がUTF-16で書かれているわけですよね?



違いますよ
encoding="UTF-16"
この部分はASCIIで書かれています。

この回答への補足

え?そうなんですか?
ということは、たとえば秀丸なんかではUTF-16でファイルを保存する機能はありますが、一部だけをASCIIにする機能はないので、XMLが書けない、ということになるのでしょうか。
UTF-16でXMLを書こうとしたら、それ専用のアプリケーションを使う必要がある、ということですか?
これってXMLの思想に反しているような気がするのですが。。。

補足日時:2005/09/22 12:45
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!