#?SuikaWiki/0.9 [9] [[XML]] と [[URI]] (or [[IRI]]) の関係について。 [12] URI を巡る規定は各規格で色々だったり、 同じ規格でも版・訂正票・実装間で二転三転多種多様だったりします。 URI の仕様は [[RFC2396]] と [[RFC2732]] で確定しているので素直にそれに従えばいいのですが、 どうもそうしたくない向きがあるようです。 例えば URI では [CODE(char)[[[SP]]]] や非 [[ASCII]] 文字など扱えない文字が多くありますが、 そのような制限を意図的に無視しようとする人・実装があります。 [WEAK[無視することでそのような制限をなし崩そうとしているのでしょう。実際 IRI でそうしてしまいそうな勢いです。]] 他にも、 XML (というか SGML) の実体をかなり自由に組み立てられる構造と相対 URI の関係が問題源だったるすなす。 [[#comment]] * システム識別子と URI [10] [[XML1.0]]/[[XML1.1]] で URI が直接関係してくるのは[[システム識別子]]だけです。 [WEAK[(そして、システム識別子が使用可能なのは[[文書型宣言]], [[実体宣言]], [[記法宣言]]です。記法宣言以外では [WEAK[(外部識別子を使う場合)]] 必須です。)]] [11] より: > [定義: [CODE(XML)[SystemLiteral]] は実体の[DFN[[RUBYB[システム識別子] [system identifier]]]]と呼びます。 システム識別子は [DEL[[INS[[WEAK[FE E26]]]] URI で、実体を取り出すのに使うことが出来るかもしれません]] [DEL[[INS[[WEAK[SE E26]]]] [INS[[INS[[WEAK[FE E66]]]] (RFC 2369 で定義され、 RFC 2732 で更新された)]] [INS[[INS[[WEAK[FE E26]]]] URI [INS[[INS[[WEAK[FE E76]]]] 参照]]で]]、[[XML処理系]]が[[置換文]]を構築するための入力を得るために[DEL[[INS[[WEAK[SE E26]]]] 参照を解くことになります]]]] [INS[[INS[[WEAK[SE E26]]]] その参照を解く過程の一部として (RFC 2369 で定義され、 RFC 2732 で更新された) URI 参照に変換されることになるものです]]。] [DEL[[INS[[WEAK[FE E76]]]] なお、 URI と共によく使われる [CODE(URI)[#]] と素片識別子は、性格には URI の一部ではありません。 XML 処理系は素片識別子がシステム識別子の一部として出現した場合には誤りとしても構いません。]] [INS[[INS[[WEAK[FE E76]]]] [[素片]]識別子 ([CODE(URI)[#]] で始まる。) がシステム識別子の一部であったなら、これは[[誤り]]です。]] XML 1.0 仕様書の適用範囲外の情報が提供されない限り、 (例えば特定の DTD で規定された特別な XML 要素型とか、 特定の応用の仕様で定義されている[[処理指令]]とかで指定されない限り、) 相対 URI はその実体宣言が出現する資源の位置からの関係とします。 [INS[[INS[SE E18]] これは宣言を開始させる [CODE(XML)[<]] が、宣言の解釈される時点で含まれている外部実体であると定義します。]] 従って URI は[[文書実体]]からの関係であったり、外部 DTD 部分集合を含んでいる実体からのであったり、 あるいは他の外部引数実体からのものであったりします。 [INS[[INS[SE E3]] URI により識別される資源を取り出そうとする時、解析器水準で (例えば実体解決器中で)、あるいは下位 (プロトコル水準、例えば [[HTTP]] [CODE(HTTP)[[[Location:]]]] [[頭]]) で redirect されるかもしれません。資源中にこの仕様の適用範囲外の追加情報が無い場合、資源の基底 URI は、常に実際に返された資源の URI となります。言い換えれば、全ての redirect を処理した後に取り出した資源の URI です。]] > [DEL[ .[INS[[WEAK[FE E78]]]] [INS[[INS[[WEAK[FE E49]]]] URI は予約文字 (RFC 2396 2.2 節参照。) や非 ASCII 文字を含んでいるかもしれません。]] XML 処理系は、 URI 中の[DEL[[INS[[WEAK[FE E49]]]] 非 ASCII]] [INS[[INS[[WEAK[FE E49]]]] そのような]] 文字を、その文字を UTF-8 の1つ以上のバイトの列として表現し、それからそのバイトを URI escape 機構で escape する (つまり各バイトを [CODE(URI)[%[VAR[HH]]]] に変換する。ここで [VAR[HH]] はバイト値の16進数表記。) ことで扱うべきです。 ]DEL] > [INS[ .[INS[[WEAK[FE E78]]]] [DEL[[INS[[WEAK[SE E4]]]] URI 参照ではある文字群について符号化と escape が必要です。禁止文字には全ての非 ASCII 文字と、 RFC 2396 の2.4節に列挙されている除外文字を含みます。但し数値記号 ([CODE(URI)[#]]) 及び百分率記号 ([CODE(URI)[%]]) 及び RFC 2732で再許可された四角括弧文字を除きます。禁止文字は次のように escape しなければなりません。]] [DEL[[INS[[WEAK[SE E26]]]] [INS[[INS[[WEAK[SE E4]]]] XML 処理系は禁止文字を次の手順で escape しなければなりません。]]]] [INS[[INS[[WEAK[SE E26]]]] システム識別子 (及び他の XML 文字列で URI 参照として使われることになるもの) は、 RFC 2396 及び RFC 2732 に従えば URI をその参照している資源を取り出すのに使う前に escape しなければならないある文字群を含んでいるかもしれません。 Escape される文字は、制御文字 [CODE(XML)[#x0]]〜[CODE(XML)[#1F]], [CODE(XML)[#7F]] (このほとんどは XML では出現できない)、間隔 [CODE(XML)[#x20]], 区切子 [CODE(XML)['<']] [CODE(XML)[#x3C]], [CODE(XML)['>']] [CODE(XML)[#x3E]], [CODE(XML)['"']] [CODE(XML)[#x22]], [RUBYB[非賢明] [[[unwise]]]]文字 [CODE(XML)['{']] [CODE(XML)[#x7B]], [CODE(XML)['}']] [CODE(XML)[#x7D]], [CODE(XML)['|']] [CODE(XML)[#x7C]], [CODE(XML)['\']] [CODE(XML)[#x5C]], [CODE(XML)['^']] [CODE(XML)[#x5E]], [CODE(XML)['`']] [CODE(XML)[#x60]], それに [CODE(XML)[#x80]] 以上の全ての文字です。 Escape は必ずしも完全に復元可能な過程ではないので、完全に必要な場合に限って可能な限り処理の連鎖の遅い過程で適用しなければなりません。特に、相対 URI を絶対 URI に変換する過程も、あるいは URI 参照をその参照を解くことを担当する過程又はソフトウェア部品に渡す過程も、 escape を行うきっかけとなるべきではありません。 Escape が行われる時には、次の手順で処理しなければなりません。]] = 各[DEL[[INS[[WEAK[SE E26]]]] 禁止]] [INS[[INS[[WEAK[SE E26]]]] escape する]]文字を UTF-8 の1つ以上のバイトの列[DEL[[INS[[WEAK[SE E26]]]] に変換]] [INS[[INS[[WEAK[SE E26]]]] で表現]]する。 = [DEL[[INS[[WEAK[SE E26]]]] 禁止文字に対応する各[DEL[[INS[[WEAK[SE E5]]]] オクテット]] [INS[[INS[[WEAK[SE E5]]]] バイト]]]] [INS[[INS[[WEAK[SE E26]]]] 結果のバイト列]]を URI escape 機構によって escape する。 (つまり、 [CODE(URI)[%[VAR[HH]]]] に変換する。ここで、 [VAR[HH]] はそのバイト値の16進表記。) = 元の文字を得た文字列で置換する。 ]INS] 修正歴: - [[FE]] -- E26 [WEAK[明確化]] URI を解決して得たバイト列を置換文の元にすることが不明瞭だった。 --- E76 URI ではなく URI 参照。素片識別子は意味がないから誤りに。 -- E49 [WEAK[本質的]] URI の予約文字に触れていなかった。 --- E78 [WEAK[本質的]] [WEAK[説明なし]] -- E66 [WEAK[編集上]] 最新の URI RFCs の参照に修正。 -- E88 [WEAK[本質的]] 文書の全ての URI を URI 参照に変更。 --- [WEAK[[[nihonLinux]] みたいだ(w 「URI URI 参照」ってなんよ?]] - [[SE]] -- E3 [WEAK[明確化]] [WEAK[説明なし]] -- E4 [WEAK[明確化]] URI 参照の解決に当たって XML 処理系が escape に責任があるという説明が SE では抜けていた。 --- E26 [WEAK[明確化]] いつ誰が escape するのか不明瞭だった。 ---- E43 [WEAK[編集上]] E26 の修正時に E3, E4, E18 を見落としていた。 -- E5 [WEAK[編集上]] [[バイト]]と[[オクテット]]は同じことだが[[数の論理]]でバイトにした。 -- E16 [WEAK[本質的]] URI RFCs をその他の参考文献から規定参考文献に変更。 -- E18 [WEAK[明確化]] >>1-2 参照 - [13] ほんとに二転三転七転八倒(謎)ですねぇ。 - [14] URI → URI 参照→ URI 参照に変換されるものと変わってきたのがおもしろおかしいw。そのうち IRI に変換されるもの、とかにまた訂正されるに違いない。 - [15] まとめると、システム識別子の値は URI ではなく、 URI 参照に変換されるものだから、 URI では使ってはいけない文字も使ってもいい、ということらしいです。ものは言いようとはまさに。 - [16] Escape が非可逆だからいくない!ってのも意味不明ですね。確かに [SAMP(URI)[http://foo.example/"/]] と [SAMP(URI)[http://foo.example/%22/]] の区別は失われますが、前者はそもそも ''URI として不正''なので、そんなものに復元する必要はないのでして。 - [17] '''XML 処理系は URI として不正な文字が含まれていたら警告'''するのがよいでしょう。仕様書がそういうのも扱えと言っている以上、誤りには残念ながら出来ませんが。 [31] [Q[システム識別子 (及び他の XML 文字列で URI 参照として使われることになるもの)]] の、システム識別子以外の XML 文字列たる URI 参照になるものって何? まさか [CODE(XMLa)[xml:base]] のような関連規格を指しているわけではありませんよね? でもシステム識別子以外に XML 本体に URI 参照って使われますか? ([[名無しさん]]) [[#comment]] * 相対 URI と基底 URI →[[.//基底]] * URI が値である属性の値における非 URI 文字の扱い →[[.//文字]] * XML 文書が情報として持つ URI [29] [[XML情報集合]]は、 URI に関わる次の[[情報項目]]を挙げています。 - 文書情報項目[基底 URI] - 要素情報項目[名前空間名] - 要素情報項目[基底 URI] - 属性情報項目[名前空間名] - 処理指令情報項目[基底 URI] - 未展開実体参照情報項目[システム識別子] - 未展開実体参照情報項目[公開識別子] - 未展開実体参照情報項目[宣言基底 URI] - 文書型宣言情報項目[システム識別子] - 文書型宣言情報項目[公開識別子] - 非解析実体情報項目[システム識別子] - 非解析実体情報項目[公開識別子] - 非解析実体情報項目[宣言基底 URI] - 記法情報項目[システム識別子] - 記法情報項目[公開識別子] - 記法情報項目[宣言基底 URI] - 名前空間情報項目[名前] [[#comment]] * メモ - [30] 本質的に XML とは関係ないけどとりあえずここに書いときますよ。[[スタイルシート]]を使うときに、[[素片識別子]]が指すのは[[原始文書]]の素片なのか、[[結果文書]]の素片なのか。[[WWWブラウザ]]の実装は後者みたいですけど (そうじゃないと色々困っちゃうもんね)、スタイルシートとは関係ない文書処理とかだと原始文書だろうし、そもそもスタイルシートごとに同じ素片識別子が別のものとして使われているかもしれない (設計としてよくないが)。つまり、結果文書の素片と解釈しちゃうと、指す内容が一意に定まらない可能性が高いんだな。かといって、 [[XSLT]] 変換を行っても原始文書の素片が結果文書の素片のどこに対応するのか情報を保持しておけっていうのは酷。