[1] [[XML]] [[文書]]は [[Unicode]] の[[文字]]の列として定義されていますが、
これはいろいろな[[文字コード]]による[[バイト列]]として表現できます。

* 仕様書

[REFS[
- [84] [CITE@EN[Extensible Markup Language (XML) 1.0 (Fifth Edition)]] ([TIME[2013-05-28 20:49:56 +09:00]] 版) <http://www.w3.org/TR/xml/#charencoding>
- [112] [CITE@en[RFC 7303 - XML Media Types]] ([TIME[2014-07-07 20:56:43 +09:00]] 版) <http://tools.ietf.org/html/rfc7303#section-3>
- [4] [CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2015-04-25 04:40:19 +09:00]] 版) <https://html.spec.whatwg.org/#read-xml>
]REFS]

* 実体の文字コード

[115] [[XML MIME実体]]は、 [[UTF-8]] を使う[['''べき''']]です [SRC[>>112]]。

[143] [[XML MIME実体]]では [[UTF-32]] を使う[['''べきではありません''']] [SRC[>>112]]。

[85] [[XML]] の[[外部解析対象実体]]は、それぞれ異なる[[文字符号化]]を使うことができます
[SRC[>>84]]。

[86] [[XML処理器]]は、 [CODE(charset)@en[[[UTF-8]]]] と 
[CODE(charset)@en[[[UTF-16]]]] の[[実体]]を[[読む]]ことができなければ[['''なりません''']]
[SRC[>>84]]。

;; [CODE(charset)@en[[[UTF-16BE]]]], [CODE(charset)@en[[[UTF-16LE]]]],
[CODE(charset)@en[[[CESU-8]]]] などはこの規定に含まれていません [SRC[>>84]]。

;; [3] [[XML]] としてはこう規定されていますが、[[応用]]によっては [[UTF-8]]
のみの利用を認めているものもあります。特定の[[応用]]のみで用いられる
[[XML処理器]]は [[UTF-8]] のみ実装しているかもしれません。
また[[バイト列]]ではなく[[文字列]]を入力として受け取る
[[XML処理器]]はどちらにも対応していないかもしれません (ただし [[XML]]
本体仕様書はそのような実装の存在を想定していません)。

[113] [[XML]] の[[外部実体]]で使っている[[文字コード]]を示す方法は3つあります [SRC[>>112]]。
[FIG(list)[
- 外部プロトコル
-- [[MIME [CODE(charset)@en[charset]]]] [[引数]]
- [[BOM]] (>>87)
- [CODE(XMLa)@en[[[encoding]]]] [[擬似属性]] (>>82)
]FIG]

[91] [CODE(charset)@en[[[UTF-8]]]] と [CODE(charset)@en[[[UTF-16]]]]
の場合を除き、 [[MIME [CODE(MIME)@en[charset]]]] などの外部の[[文字符号化]]情報か、
[CODE(XMLa)@en[[[encoding]]]] [[擬似属性]]がなければ[['''なりません''']]
[SRC[>>84]]。

[117] [[XML対応]]の [[MIME]] [[producer]] は、 [[UTF-8]] 以外で
[CODE(XMLa)@en[[[encoding]]]] [[擬似属性]]がない [[XML MIME実体]]について、
[CODE(MIME)@en[[[charset]]]] [[引数]]と [[BOM]] の一方又は両方を指定する[['''べき''']]です
[SRC[>>112]]。その場合 [CODE(XMLa)@en[[[encoding]]]] 
[[擬似属性]]が実際の[[文字符号化]]と一致していないと分かっている時には、
それを修正または削除する[['''べき''']]です [SRC[>>112]]。

[127] [[実体]]の[[文字コード]]は、次のようにして決定します。

[FIG(steps)[
= [130] 外部の[[輸送プロトコル]]の情報があれば、それに依ります。
=- [131] [[XML MIME実体]]では、次のように定義されています [SRC[>>112]]。
=-= [128] [[BOM]] があれば、それによって決定します [SRC[>>112]]。
=-= [129] [[MIME]] [CODE(MIME)@en[[[charset]]]] [[引数]]があれば、
それによって決定します [SRC[>>112]]。
=-=- [8] [[sniffed MIME type]] ではなく、元々指定された [[MIME型]]を使います [SRC[>>4]]。
= [132] 外部の[[輸送プロトコル]]からの情報がない場合、
== [133] [[BOM]] や [CODE(XMLa)@en[[[encoding]]]] [[擬似属性]]があれば、それによって決定します。
== [109] [CODE(charset)@en[[[UTF-8]]]] か [CODE(charset)@en[[[UTF-16]]]] の [[BOM]] がなく、 
[CODE(XMLa)@en[[[encoding]]]] [[擬似属性]]がなく、
[[UTF-8]] でもないのは[[致死的誤り]]です [SRC[>>84]]。
== [134] それ以外なら [[UTF-8]] です。
=- [108] なお、 [CODE(XMLa)@en[[[encoding]]]] 
[[擬似属性]]の値と実際の[[文字符号化]]が一致しないのは[[致死的誤り]]です [SRC[>>84]]。
]FIG]

;; [135] 外部情報がある場合に外部情報と [CODE(XMLa)@en[[[encoding]]]]
が一致しないのはエラーとはされていません。

;; [136] >>131 はなぜか [['''SHOULD''']] とされています [SRC[>>112]]。

;; [137] [CODE(MIME)@en[[[charset]]]] より [[BOM]] が優先されることになっていますが、
これは [[Webブラウザー]]の実装や [[HTML]] における文字コード判定と一致しています。

[139] [[XML未対応]]の [[MIME]] [[consumer]] は、 [CODE(MIME)@en[[[charset]]]]
[[引数]]が無い場合に、既定の[[文字符号化]]を仮定する[['''べき''']]ではありません [SRC[>>112]]。

;; [138] [[RFC 3023]] 時代までは、 [CODE(MIME)@en[[[text/*]]]] で
[CODE(MIME)@en[[[charset]]]] [[引数]]がない場合は [CODE(charset)@en[[[US-ASCII]]]]
とみなすことになっていました ([[XML対応]]か否かによらず)。 
(しかし誰もそれに従っていませんでした。)

;; [140] 仮定せずにどうするべきかは明記されていません。
([CODE(MIME)@en[[[text/plain]]]] ではなく)
[CODE(MIME)@en[[[application/octet-stream]]]] とみなすべきということでしょうか。

;; [141] [CODE(MIME)@en[[[charset]]]] があったとしても、 [[BOM]]
もあり、両者が一致していない場合、 [[XML対応]]か[[XML未対応]]かで動作が変わってしまうのですが、
それでいいのでしょうか。 [[XML未対応]]なら一切の[[文字コード]]処理をするべきではない気がします。

[110] [[処理]]できない[[文字符号化]]の[[実体]]に遭遇したら[[致死的誤り]]です [SRC[>>84]]。

[144] [[UTF-32]] に対応していない [[XML MIME実体]]の [[consumer]] であっても、
[[UTF-32]] の [[BOM]] は認識して適当なエラーを出す[['''べき''']]です [SRC[>>112]]。

;; [145] これは [[UTF-32]] への一切の対応を削除した [[Webブラウザー]]や [[HTML]]
や [[Encoding Standard]] の方針とは相反するものです。

[111] [[実体]]の[[文字符号化]]において[[合法]]でない[[バイト列]]に遭遇したら[[致死的誤り]]です
[SRC[>>84]]。

-*-*-

[15] [[Web]] での処理は、 [[encoding sniffing algorithm]],
[[Webにおける文字コード]]も参照。

[16] [[SRGS]] の [[ABNF形]]の [[charset sniffing]] の処理の規定では、 
[CITE[XML]] 仕様書が参照されています。

* MIME [CODE(MIME)@en[charset]] 引数

[121] [CODE(MIME)@en[[[text/xml]]]]、[CODE(MIME)@en[[[application/xml]]]]、
[CODE(MIME)@en[[[text/xml-external-parsed-entity]]]]、
[CODE(MIME)@en[[[application/xml-external-parsed-entity]]]]、
[CODE(MIME)@en[[[application/xml-dtd]]]]、
および [[RFC 7303]] を参照するその他の [[MIME型]]における [DFN[[CODE(MIME)@en[[[charset]]]]]]
[[引数]]は、 [[RFC 7303]] で定義されており、当該 [[XML MIME実体]]の[[文字コード]]を表しています。

;; [122] >>121 以外の [[XML MIME型]]の [CODE(MIME)@en[[[charset]]]] [[引数]]は、
異なる定義の[[引数]]です。 (あるいは [CODE(MIME)@en[[[charset]]]]
[[引数]]が定義されていないこともあります。)

;; [123] [[RFC 7303]] の前の [[RFC 3023]] 時代の多くの [[XML MIME型]]は、
[[RFC 3023]] の [CODE(MIME)@en[[[charset]]]] [[引数]]の定義を参照しています。
現実的にはそれらも >>121 と同じものとして扱うべきでしょうが、
仕様上厳密には両者の定義は異なります。

[146] 値としては [[MIME charset]] が想定されているものと思われますが、
[[RFC]] にはまったく言及がありません。

;; [147] しかし実際の [[Webブラウザー]]は [[MIME charset]] ではなく [[Encoding Standard]]
に従い解釈する(べき)ものと思われます。

[124] [[XML未対応]]の [[MIME]] [[producer]] は、 [[文字符号化]]が確実に分かっている場合を除き、
[[XML MIME実体]]に [CODE(MIME)@en[[[charset]]]] [[引数]]を設定しては[['''なりません''']]
[SRC[>>112]]。

[125] [[XML]] [[MIME]] [[producer]] は、[[利用者]]が [[XML MIME実体]]に設定する値を指定する方法を提供する[['''べき''']]です
[SRC[>>112]]。

[EG[
[126] 例えば、[[ファイル名]]の[[拡張子]]から [CODE(MIME)@en[[[charset]]]]
を決めるように設定できるような実装方法が考えられます [SRC[>>112]]。
]EG]

* BOM

[87] [CODE(charset)@en[[[UTF-16]]]] の[[実体]]は [[BOM]] から始まらなければ[['''なりません''']]
[SRC[>>84]]。

[116] [[XML MIME実体]]では [[BOM]] のない [[UTF-8]] を使う[['''べき''']]です [SRC[>>112]]。

;; [88] [CODE(charset)@en[[[UTF-8]]]] の[[実体]]は [[BOM]] から始めることができます [SRC[>>84]]
が、[[必須]]ではありません。

[90] [[外部実体]]の[[置換文]]の先頭が [CODE(char)[[[U+FEFF]]]] で[[テキスト宣言]]が無い時には、
[[UTF-8]] であっても [[BOM]] からはじめなければ[['''なりません''']] [SRC[>>84]]。

[118] [[XML対応]]の [[MIME]] [[producer]] は、 [[Unicode]] 以外の[[XML MIME実体]]の先頭が
0xFE 0xFF, 0xFF 0xFE, 0xEF 0xBB 0xBF のいずれかとなるような場合、
[[テキスト宣言]]がなければ[['''なりません''']] [SRC[>>112]]。

;; [119] これらは [[UTF-8]] や [[UTF-16]] の [[BOM]] と区別できないからです。
なお、 [[Unicode]] 以外となっているので、 [[UTF-8]] や [[UTF-16]]
以外の [[Unicode]] 系[[文字コード]] ([[CESU-8]] など) の [[BOM]]
ならこの要件は適用されないことになります。

;; [120] 特に限定されていないので、 [CODE(MIME)@en[[[charset]]]]
[[引数]]があってもこの要件は適用されます。

[89] [[XML処理器]]は、 [[BOM]] によって [CODE(charset)@en[[[UTF-8]]]] と 
[CODE(charset)@en[[[UTF-16]]]] の[[文書]]を判別できなければ[['''なりません''']] [SRC[>>84]]。

;; [114] [CODE(charset)@en[[[UTF-8]]]] と [CODE(charset)@en[[[UTF-16]]]]
以外の[[文字コード]]に関しては、 [[XML]] としての [[BOM]] に関する規定は特にありません。

* [CODE(XMLa)@en[encoding]] 擬似属性

[82] [[XML宣言]]・[[テキスト宣言]]の [DFN[[CODE(XMLa)@en[[[encoding]]]]]]
[[擬似属性]] (正式には[RUBYB[[[符号化宣言]]]@en[encoding declaration]])
は、当該[[実体]]の[[文字コード]]を指定するものです。

[83] 何らかの[[文字コード]]で[[符号化]]された[[バイト列]]の中にその[[文字コード]]を表す情報が含まれていても一般には意味がありませんが、
利用され得る[[文字コード]]の[[集合]]は有限なので、 [[sniffing]] によって実用上十分有用です。

** 文脈

[97] [[XML宣言]]または[[テキスト宣言]]で、 [CODE(XMLa)@en[[[version]]]]
[[擬似属性]]の直後に1回だけ指定できます。 [[テキスト宣言]]では
[CODE(XMLa)@en[[[version]]]] [[擬似属性]]が省略可能なので、
その場合[[対象名]]の直後となります。 [[テキスト宣言]]では直後が [CODE[[[pic]]]]
でなければなりません。[[XML宣言]]ではその前に [CODE(XMLa)@en[[[standalone]]]]
[[擬似属性]]を指定することもできます。

[142] [CODE(charset)@en[[[UTF-16BE]]]] や [CODE(charset)@en[[[UTF-16LE]]]]、
[CODE(charset)@en[[[UTF-32BE]]]]、[CODE(charset)@en[[[UTF-32LE]]]]
の場合、 [CODE(XMLa)@en[[[encoding]]]] [[擬似属性]]を指定する[['''べき''']]です [SRC[>>112]]。

** 構文

[92] [[要素]]の[[属性]]の構文と似ていますが、特殊な構文として定義されています。

[94] [[擬似属性]]は[[属性名]]、[CODE[[[=]]]]、[[属性値]]で構成されます。
[[属性名]]は小文字の [CODE(XML)@en[[[encoding]]]] です。[[属性値]]は[[符号化名]]で、
[CODE[[["]]]] (のみ) か [CODE[[[']]]] (のみ) で前後を括らなければなりません。
[[文字参照]]は使えません。 [SRC[>>84]]

[93] 本[[擬似属性]]の前には [CODE[[[S]]]] が必要です。後に次の[[擬似属性]]が続く場合には、
間の [CODE[[[S]]]] も必要です。 [SRC[>>84]]

[FIG(railroad)[
= [CODE[[[S]]]]
= [CODE(XML)@en[[[encoding]]]]
= [CODE[[[=]]]]
= |
== =
=== [CODE[[["]]]]
=== [[符号化名]]
=== [CODE[[["]]]]
== =
=== [CODE[[[']]]]
=== [[符号化名]]
=== [CODE[[[']]]]
]FIG]

*符号化名

[12] XML の [[XML宣言]]・[[文宣言]]の符号化宣言
([[encoding]] 擬似属性) に指定できる値には、 MIME charset
パラメーターの場合と同じ、 IANA 登録簿の名前も含まれます。

[95] ただし、 XML の場合は名前の制限が MIME や IANA 登録簿より厳しくなっています。

[13] [[符号化名]]で使える[[文字]]は、[[ASCII英数字]]と [CODE[[[.]]]]、
[CODE[[[_]]]]、[CODE[[[-]]]] です。ただし先頭は[[ASCIIアルファベット]]でなければなりません。
[SRC[>>84]]

[FIG(railroad)[
= |
== [[ASCII大文字]]
== [[ASCII小文字]]
= *
== |
=== [[ASCII大文字]]
=== [[ASCII小文字]]
=== [[ASCII数字]]
=== [CODE[[[.]]]]
=== [CODE[[[_]]]]
=== [CODE[[[-]]]]
]FIG]

[103] [[XML処理器]]は、[[符号化名]]を[[大文字・小文字不区別]]として扱う[['''べき''']]です
[SRC[>>84]]。

;; なぜか[['''推奨''']]にとどまっています。

[2] [[符号化名]]の意味は、次の通り述べられています [SRC[>>84]]。

;; ただし、なぜかこれらはいずれも「[['''SHOULD''']]」となっています。

[FIG(list)[
- [98] [CODE[[[UTF-8]]]]、[CODE[[[UTF-16]]]]、[CODE[[[ISO-10646-UCS-2]]]]、
[CODE[[[ISO-10646-UCS-4]]]] は、 [[Unicode]]/[[ISO/IEC 10646]] のそれぞれの[[文字コード]]を表します。
- [99] [CODE(charset)@en[[[ISO-8859-[VAR[n]]]]]] は、 [[ISO/IEC 8859]] 第[VAR[n]]部の[[文字コード]]を表します。
- [100] [CODE(charset)@en[[[ISO-2022-JP]]]], [CODE(charset)@en[[[Shift_JIS]]]],
[CODE(charset)@en[[[EUC-JP]]]] は、 [[JIS X 0208:1997]] のそれぞれの[[文字コード]]を表します。
- [101] その他の [[IANA charset]] 名は、当該[[文字コード]]を表します。
- [102] それ以外の[[文字コード]]は、 [CODE[[[x-]]]] で始まる名前を使います。
]FIG]

[105] [[XML処理器]]は、[[符号化名]]を [[IANA登録簿]]の[[文字符号化]]として解釈するか、
未知のものとして扱うかのいずれかとする[['''べき''']]です。 [SRC[>>84]]

;; [107] >>98, >>99, >>100 によりいくつかの [[charset]] 名はなぜか 
[[IANA登録簿]]を参照していません。これは厳密に解釈すると 
[[IANA登録簿]]と異なる[[文字コード]]を指しているものや、 [[IANA登録簿]]にない
[[ISO/IEC 8859]] の仕様書を指しているものも含まれています。例えば 
[CODE(charset)@en[[[ISO-2022-JP]]]] は [[IANA登録簿]]が参照する [[RFC 1468]]
の定義と [[JIS X 0208:1997]] に含まれる定義が一致していません。
ところが >>105 の通り[[処理器]]に対しては [[IANA登録簿]]に従うことを求めており、
ますます意図するところが不明です。

[106] [[XML処理器]]は、 [[IANA登録簿]]のすべての[[文字符号化]]に対応する必要はありません
[SRC[>>84]]。

;; [104] これだけ [['''SHOULD''']] のオンパレードかつ曖昧な定義で、
[[相互運用性]]を確保するつもりはあるのでしょうか。

[96] 実際には [[XML処理器]]で非 IANA
名で [CODE[[[x-]]]] で始まらないものを使えるものも多いようです。
中には、 [CODE(charset)[[[シフト符号化表現]]]] なんて値まで使える実装もあるようです。 
(これは >>13 に違反していますが。))

* DOM

[5] [[XML構文解析器]]は、[[XML文書]]の[[文字符号化]]を決定したら、
これを[[文書の文字符号化]]として設定しなければ[['''なりません''']] [SRC[>>4]]。

;; [6] 仕様上この正確なタイミングは決められていませんが、 [[XML]]
の場合は[[文書]]の[[構文解析器]]の途中で[[文字符号化]]が変更されることはありませんから、
必ず[[スクリプト]]の実行より前になります。

;; [7] [[update the session history with the new page]] より前に実行されなければならないとの規定はありませんから、
他の[[フレーム]]の[[スクリプト]]からは設定前にアクセスできてしまうのかもしれません。

* メモ

[148] [CITE@en[RFC 4918 - HTTP Extensions for Web Distributed Authoring and Versioning (WebDAV)]]
( ([TIME[2014-09-21 17:04:59 +09:00]] 版))
<http://tools.ietf.org/html/rfc4918#appendix-F.1>

[9] [CITE@EN[XQuery 3.1: An XML Query Language]]
([TIME[2017-03-20 09:23:33 +09:00]])
<https://www.w3.org/TR/2017/REC-xquery-31-20170321/#dt-encoding-declaration>

[10] [CITE@en[ERB decision: Character sets]]
([[Jon Bosak]]著, [TIME[1997-06-23 13:41:05 +09:00]])
<https://lists.w3.org/Archives/Public/w3c-sgml-wg/1997Jun/0461.html>

[11] [CITE@en[Determination of Encoding (Re: Invasion of the pseudo-people ...)]]
([[Murata Makoto]]著, [TIME[1997-06-14 21:07:25 +09:00]])
<https://lists.w3.org/Archives/Public/w3c-sgml-wg/1997Jun/0258.html>

[14] [CITE@en[Re: Comments on XML Part 1 from Japanese experts]]
([[Murata Makoto]]著, [TIME[1997-06-07 18:15:24 +09:00]])
<https://lists.w3.org/Archives/Public/w3c-sgml-wg/1997Jun/0130.html>

[17] [CITE[使用できる文字エンコーディング]], [TIME[2019-07-03T08:13:49.000Z]], [TIME[2025-11-19T14:44:34.308Z]] <https://itpfdoc.hitachi.co.jp/manuals/3021/3021360820/ADX20125.HTM>


