予約展開

式 (URI 雛形)

[2] URI雛形 (expression) は、 {} で囲まれた部分と {} です >>1

仕様書

[14] (expression) は、 {演算子変数リスト} で構成されます。ただし演算子は省略できます。 >>13

  1. {
  2. ?
    1. 演算子
  3. 変数リスト
  4. }

演算子と式型

[4] 展開の過程は、式型 (expression type) により決まります >>3, >>13式型演算子によって表されます >>13

[5] 演算子が省略された場合の式型単純文字列展開 (simple string expansion) です >>3, >>13未予約文字以外をすべてパーセント符号化して展開することを表しています。 区切り文字に , を使います。

[15] 演算子には次のものがあります。

  • + (予約展開 (reserved expansion) ) は、 未予約文字予約文字パーセント符号化はそのままで、 それ以外をパーセント符号化して展開することを表しています。 区切り文字に , を使います。
  • # は、 + と同じですが、先頭に # を付与します。
  • . は、単純文字列展開と同じですが、先頭や区切り文字に . を使います。
  • / は、単純文字列展開と同じですが、先頭や区切り文字に / を使います。
  • ; は、値の前に変数名と = を付与し、先頭や区切り文字に ; を使います。
  • ? は、値の前に変数名と = を付与し、先頭に ?、区切り文字に & を使います。
  • & は、値の前に変数名と = を付与し、先頭や区切り文字に & を使います。

[49] 次の演算子は予約されています >>13

変数リスト

[25] 雛形式に指定する変数リスト (variable-list) は、 1つ以上変数指定子コンマ区切りリストです。 >>24

  1. 変数指定子
  2. *
    1. ,
    2. 変数指定子

[26] 変数指定子 (variable specifier) (varspec) は、変数名と省略可能な値修飾子です。 >>24

  1. 変数名
  2. ?
    1. 値修飾子

[27] 値修飾子 (value modifier) には、 接頭辞修飾子 (:) と爆発修飾子 (*) があります >>24

変数

[28] 変数名は、

... という役割を持ちます >>24

[32] 変数名は、ASCIIラテン文字ASCII数字_パーセント符号化. の1つ以上の列です。ただし . は最初と最後には使えません。 >>24

  1. |
    1. ASCIIラテン文字
    2. ASCII数字
    3. _
    4. パーセント符号化
  2. *
    1. ?
      1. .
    2. |
      1. ASCIIラテン文字
      2. ASCII数字
      3. _
      4. パーセント符号化

[33] 変数名は、大文字・小文字を区別します >>24

[34] パーセント符号化変数名の一部として扱い、 復号はしません。パーセント符号化された変数名とそれを復号した変数名は、 異なるものとします。 >>24

[83] RFC 6570 は、変数に割り当てられる値のデータモデルを明確に規定していません。

[84] 仕様書本文全般では、文字列リスト連想配列の3つのデータ型を扱っています。 また、未定義なる状態を設けています。

[52] 文字列 (string) は、Unicode符号位置の0個以上の列であるようです。 空文字列未定義は異なります >>24

[85] 利用者の入力は NFC正規化するべき >>82 と規定されていますが、一般にはそのような制約は設けられていません。

[86] リスト (list) は、文字列の0個以上の列であるようです。 順序を持つか否かは明記されていませんが、常識的には順序を持つと解されます。

[87] 連想配列 (associative array) は、名前 (name) (value) の組の0個以上の列であるようです。 附属書Aのアルゴリズム例には「連想配列その他名前と値の (pair) 」 などといった表現もあり、統一されていません。順序を持つか否かは明記されていません。

[90] 連想配列の名前は、文字列であるようです。重複に関する制約は明記されていません。

[91] 連想配列の値は、文字列または未定義であるようです。

[88] 構造体 (structure) は、連想配列であるものとして扱います。 ただし階層は . によって名前を連結することで表現します。 一部の値が定義されない場合には、値が定義された組のみ含めます。 >>81

[89] 構造体は仕様書中1箇所のみで唐突に登場し、 附属書Aのアルゴリズム例にも挙げられていません。

[92] 変数連想配列の値は、定義されているか、未定義かのいずれかであるようです。 未定義は、 nullundef で表す特別な値です >>24

[53] リストに含まれる個数が0個の時や、連想配列の名前と値の組の個数が0個の時や、 名前がすべて未定義に関連付けられている時には、未定義とします。 >>24

[94] 雛形式は、雛形処理器が知らない変数や、 未定義値に設定された変数を参照しても構いません >>24展開の過程で無視されますが、誤りではありません。

実装水準

[6] URI雛形では式型集合水準 (level) と呼んでいます。 水準1から水準4までがあります。

[12] 低水準の実装は、より高水準の構文に対応しなくても構いませんが、 対応して利用者に未対応である旨を伝えるべきです >>11

展開

[18] は、次のように展開します。

  1. [19] 先頭の { と末尾の } を除去します。
  2. [20] 最初の文字が演算子なら、これにより式型を決定します。 その文字は除去します。 >>17
  3. [21] それ以外なら、単純文字列展開式型とします >>17
  4. [23] 未対応の式型なら、誤りを返します。
  5. [95] 残った文字列が構文的に正しくないなら、誤りを返します。
  6. [22] 残った文字列を式型依存の方法で処理します。

[93] URI雛形全体の展開の処理も参照。

[50] 1つの URI雛形では、同名の変数はすべて同じ値として処理しなければなりません >>16

[51] これは入力として用いられる値が同じであるだけであり、 出力として得られる展開は異なることがあります。

[71] 式型に依存した展開は、次のように求めます。

  1. [72] 変数リストに含まれる変数のリストを用意します。
  2. [54] リストから、値が未定義のものを除去します >>16
  3. [55] その結果リストが空になった場合は、空文字列を返し、ここで停止します >>16
  4. [73] リストの値それぞれの展開を求めます。
  5. [76] 演算子./;& なら、 演算子と同じ文字の後にリストの各値を演算子と同じ文字で連結した値を返します >>17
  6. [77] 演算子? なら、 ? の後にリストの各値を & で連結した値を返します >>17
  7. [75] 演算子# なら、演算子と同じ文字の後にリストの各値を , で連結した値を返します >>17
  8. [74] 式型がそれ以外なら、リストの各値を , で連結した値を返します >>17

[56] 値の展開は、次のように求めます。

  1. [58] 値が単純な文字列なら、
    1. [59] 接頭辞修飾子があれば、適用します >>16
    2. [78] 演算子;?& なら、 変数名雛形リテラル同様に符号化したもの >>17=>>57 により符号化 >>16 したものを連結し、返します。 ただし演算子;= の後が空文字列になる時は、 = を含めません >>17
    3. [60] そうでなければ、 >>57 により符号化 >>16 したものを返します。
  2. [62] 値が連想配列なら、
    1. [63] 爆発修飾子がなければ、
      1. [64] 含まれる名前と値の組のうち、値が定義されているものを使って >>16、 (名前1、値1、名前2、値2、...) のようなリストを作成します。
      2. [65] リストの要素それぞれに >>57符号化を適用します。
      3. [79] 演算子;?& なら、 変数名雛形リテラル同様に符号化したもの >>17=、リストの要素を , で連結 >>16 したものを連結し、返します。 ただし演算子;= の後が空文字列になる時は、 = を含めません >>17
      4. [35] そうでなければ、リストの要素を , で連結 >>16 したものを返します。
    2. [36] 爆発修飾子があれば、
      1. [66] 含まれる名前と値の組のうち、値が定義されているものについて >>16
        1. [37] 値が空文字列で、演算子? でも & でもなければ、名前に >>57符号化を適用します >>16
        2. [38] それ以外なら、名前に >>57符号化を適用したものと値に >>57符号化を適用したものを = で連結します >>16
      2. [39] 得られた値を連結します。この時、演算子?& なら & を、 ;/. なら演算子と同じ文字を、それ以外なら , を区切りに使います。 >>16
  3. [41] 値がリストなら、
    1. [42] 構成要素それぞれに >>57符号化を適用します。
    2. [44] 爆発修飾子がなければ、
      1. [80] 演算子;?& なら、 変数名雛形リテラル同様に符号化したもの >>17=、各値を , で連結 >>16 したものを連結し、返します。 ただし演算子;= の後が空文字列になる時は、 = を含めません >>17
      2. [43] そうでなければ、各値を , で連結 >>16 したものを返します。
    3. [48] 爆発修飾子があれば、
      1. [45] 演算子;, ?, & なら、 各値の前に変数名= を連結します >>16。 ただし変数名雛形リテラルと同じ方法で符号化します。
      2. [46] 各値を >>39 と同じ文字で区切って連結します >>16

[57] 文字列値の符号化は次のように行います >>16

  1. [47] UTF-8符号化します。
  2. [67] 演算子+# なら、 RFC 3986 unreservedRFC 3986 reservedパーセント符号化以外は、パーセント符号化します。
  3. [68] それ以外なら、RFC 3986 unreserved 以外は、パーセント符号化します。

[69] +# では、 入力中のパーセント符号化以外の % は、パーセント符号化が必要です。 入力中のパーセント符号化はそのまま出力されます。 なおこれは雛形リテラルに適用されるのと同じ符号化です。
[70] それ以外では、入力中のパーセント符号化は認識されず、すべての %パーセント符号化が必要です。