[31] [[SGML]] および [[XML]] において、[[マーク付け宣言]]の一部を予め定義しておいたものを[DFN[[RUBYB[引数実体]@en[parameter entity]]]]、
これを参照するものを[DFN[[RUBYB[引数実体参照]@en[parameter entity reference]]]]といいます。

;; [46] [[XML]] の仕様書では[[引数実体]]を [DFN[[[PE]]]] とも略します。また、[DFN[[[パラメーター実体]]]]とも訳されます。

[32] [[XML]] では[[引数実体参照]]は [[DTD]] でのみ使うことができます。 [[SGML]] では[[引数実体参照]]は [[DTD]]
([[文書型宣言]]) のみならず、[[連結型宣言]]や[[文書実現値]]内の[[マーク区間宣言]]でも使うことができます。

[33] [[引数実体]]は、[[マーク付け宣言]]の内部、すなわち[[引数]] ([[パラメーター]]) 
として使うことができる[[実体]]であることからこの呼称があります。 ([[XML]] では[[引数実体]]以外で
「[[引数]]」という語を使わないことから、この元の意味がわかりにくくなっています。 [[DTD]]
はその全体が[[文書型宣言]]の[[引数]]です。)

* XML における引数実体参照

[34] [[XML]] では、[[引数実体参照]]はその利用される文脈により次の3種類に大別できます。
[FIG(list)[
- [35] [[マーク付け宣言]]等の前後に置かれるもの ([CODE(XML)@en[[[DeclSep]]]] として使われるもの)
- [36] [[マーク付け宣言]]や[[条件区間]]の[[キーワード]]部分に置かれるもの
- [37] [[実体値]]中に置かれるもの
]FIG]

[47] [[引数実体]]は1種類で、[[引数実体参照]]が使われる文脈が3種類です。
同じ[[引数実体]]を同時に別の文脈で使うこともできます。
(ただし3つすべての文脈で構文的に正しい形に展開されるような[[引数実体]]を定義することは不可能です。)

;; [48] アクセスのたびに返す値が異なるような [[URL]] を[[システム識別子]]として指定した[[引数実体]]と、
[[引数実体参照]]の展開のたびに[[システム識別子]]で指定された [[URL]]
にアクセスするような[[XML処理器]]を使えば、各文脈でそれぞれ適切な構文で返すことは原理的には可能です。
実用上の価値は無いでしょう。 ([[実体参照]]の展開のたびにアクセスが発生するべきかしないべきなのかについて、
[[XML]] 仕様上は規定がありません。)

[39] [[XML]] 仕様書の [[EBNF]] 構文では >>35 と >>37 は明記されていますが、 >>36 は明記されておらず、
[[引数実体参照]]を[[展開]]した結果が [[EBNF]] 構文により記述されていることになっています。

[38] [[内部部分集合]]で使えるのは >>35 だけです。 >>36 や >>37 は禁じられています。

[41] >>36 や >>37 は、[[外部部分集合]]と[[外部引数実体]]では使えるとされています。

[42] >>35 によって[[参照]]される[[内部引数実体]]の内部で >>36 や >>37 が使えるのかは明記されていません。

[40] [[XML]] の[[処理器]]は、[[外部実体]]への[[参照]]を[[展開]]することが要求されていません。
([[妥当性検証]]のためには[[展開]]しなければなりませんが。) しかし[[内部実体]]は[[処理]]、[[展開]]しなければならないようです。

[43] >>42 は、 ([[内部部分集合]]から[[参照]]されている[[内部引数実体]]が[[内部部分集合]]の一部でないと解釈するなら)
禁止されていない以上、使えると解釈できます。しかし >>40 と >>38 
によって[[妥当性検証]]を行わない[[処理器]]の実装を簡易化することが元々の意図と推測されますから、
[[内部引数実体]]でも禁止するのが本来の意図である、とも推測できます。

[44] [[Chrome]] は[[内部部分集合]]の >>35 すら対応していないようで、[[実体]]が[[宣言]]されていないとの[[致死的誤り]]になります。
[TIME[2014-02-24T12:20:43.900Z]]

[45] [[Firefox]] は >>35 に対応しています。[[内部部分集合]]から[[参照]]される[[内部引数実体]]に
>>36 や >>37 が含まれる場合、元の[[引数実体参照]]が不正であるとの[[致死的誤り]]になります。 [TIME[2014-02-24T12:24:34.000Z]]

* メモ

[24] 
>
:[INS[[[JISX4151]]‐1992]] 3. (209) 引数実体 (parameter entity):
[[マーク宣言]][[引数]]から[[参照]]することができる[[実体]]。
:[INS[[[WebSGML]]]] K.2.5.3 パラメタ実体 (parameter entity):
[4.225 (JIS X 4151 においては、3. (209)) を参照。]
[[外部部分集合実体]]であるか、又は[[パラメタ実体名]]をつけて宣言された実体。

[25] >>24 じゃあ[[宣言部分集合]]の地の部分の引数実体参照はどうなのだと一瞬思いますが、よくみると宣言部分集合自体[[文書型宣言]]とかの引数なわけですから、
この定義で全く問題ない。

[26] 引数実体は[[一般実体]]と同じく[[実体宣言]]を使って宣言しますが、微妙に異なる書式であり、[[実体名]]の[[名前空間]]も異なります。

[27] [[内部実体]]のことも[[外部実体]]のこともありますが、一般実体とは異なり必ず[[解析実体]]です。また、[[参照]]される場合は必ず[[引数実体参照]]の形を取り、他に参照する方法はありません。

[28] 有効範囲は宣言の直後からで、[[宣言部分集合]], [[マーク宣言]] ([[マーク区間宣言]]を含む。) の適当な (構文上認められた) 場所です。

[29] [[XML]] の場合は[[文書型宣言]]の宣言部分集合内でのみ有効です。

[30] >>24 素の SGML と Web SGML では定義が違っていますが、この改訂には2つの意味があるでしょう。(1) 見方の違い : 素の SGML では参照する側からみた定義だったのが、 Web SGML では定義する側から見た定義になっている。 (2) 意味の拡大 : 素の SGML では引数実体であるか定義上曖昧であった、外部部分集合実体が Web SGML では引数実体の一種になっています。

[15] [[SGML]] や [[XML]] では [[DTD]] の[[マーク宣言]]などの表記に[[パラメーター実体]]参照が使えます。

[16] XML の仕様書では、他の部分では[[実体参照]]が使える部分が [[EBNF]] 構文ではっきり示してあるのに、 DTD 中のパラメーター実体参照が書ける場所については自然言語での説明しかありません。

[17] まず、 [[DOCTYPE]] 宣言中の[[内部部分集合]]のマーク宣言内にパラメーター実体参照は一切書けません ([CODE(XML)[EntityValue]] 内も書けないみたいです)。 (マーク宣言外、つまり地の部分には書けます。)

[18] で、マーク宣言「内」とはどこからどこまでか、
なのですが、幾つかの XML parser の実装を調べてみました。
([[Mozilla]] は[[外部解析実体]]を読まないので問題外、 [[WinIE]] ([[MSXML]]) とか [[W3C]] の [[Validator]] で試してみる。もっとも W3C のは本来 [[SGML]] parser だから、あてになるのかは不明。)
--MSXML も W3C Validator も、次のは意図したように解釈してくれました。
---[SAMP(XML)[<!ENTITY % e1 "type"><!ENTITY % e2 "ANY"><!ELEMENT%e1;%e2;>]]
---[SAMP(XML)[<!ENTITY % e "type ANY"><!ELEMENT %e1;>]]
--次のようなものはだめでした。
---[SAMP(XML)[<!ENTITY % e "ELEMENT type ANY>"><!%e1;]]
---[SAMP(XML)[<!ENTITY % e "ELEMENT type ANY"><!%e1;>]]
--ということで、単純に [CODE(XML)[<![VAR[declaration]]]] の後で [CODE(XML)[>]] の前までかパラメーター実体参照による置換の対象のようです。 ([[整形式]]制約から当たり前といえば当たり前です。ただし、宣言名の直後に [CODE(XML)[S]] なしに [CODE(XML)[%]] が来てもよいこと、パラメーター実体参照とそのまわりがくっついていても展開の際に [CODE[U+0020]] が補われることに注意したいところです。)

[19] こんなのもありだ。 [SAMP(XML)[<!ENTITY % include " INCLUDE[<!ENTITY % q '"'><!ENTITY name %q;name=foo%q;>  "><![%include;]]>]]。ところが、ちょっと修正をして [SAMP(XML)[<![%include;]>]] とか [SAMP(XML)[<!%include;]]>]] となるようではうまくいかない。

[20] >>19 ここで思い出されるのが、 [CODE[U+0020]] を補う規則。確かに >>19 の悪い例だと、 [SAMP(XML)[<! [ INCLUDE[]] とか [SAMP(XML)[] ]>]] とかになるからおかしい。

[21] >>18 整形式制約というか、[[XML//妥当性制約]>>4]だよな。 (パラメーター実体の外に出ている [CODE(XML)[<]] が整形式制約, 中に入っている (置換文の) [CODE(XML)[>]] が妥当性制約に引っ掛かる。)

[22] >>16 たしかに完全に BNF で表現するのは困難ではあるのですが...

[23] >>22 全ての組み合わせは実質不可能だけど、せめて SGML 仕様書程度の記述はするべき、というか、 [CODE(SGML)[[[ts]]]], [CODE(SGML)[[[ps]]]], [CODE(SGML)[[[ds]]]] 程度の区別はするべきだったと。

[1] 【[[SGML]]/[[XML]]】 [[DTD]] 中で[[マーク宣言]]やその[[引数]]を値として持つ[[変数]]
(というか[[定数]]) 的に使用される[[実体参照]]。
[[パラメーター実体参照]], [[パラメタ実体参照]]などとも。
Parameter entity reference。

[2] [[規格参照具象構文]]だとして、
[PRE[
<!ENTITY % lt '<'>
<!ENTITY % a "%lt;!ENTITY ent 'entity value'>">
%a;
]PRE]

は適当でしょうか?

[[JISX4151]]‐1992 9.1.4 は、
「[CODE(SGML)[[[ds]]]] としての引数実体参照は、
0個以上の完全なマーク宣言と [CODE(SGML)[ds]]
とからなる実体を参照しなければならない」と述べています。

この例では [SAMP(SGML)[%a;]] も、それに含まれる 
[SAMP(SGML)[%lt;]] も [CODE(SGML)[ds]] 
としての引数実体参照とみなされます。
[SAMP(SGML)[<]] だけからなるマーク宣言は存在しませんから、
この例は'''不正'''です。

[3] それでは
[PRE[
<!ENTITY % q '"'>
<!ENTITY % a "<!ENTITY ent %q;entity value%q;>">
%a;
]PRE]

は適当でしょうか? ちなみに [[MSXML]] では通ってしまいます。

JIS X 4151‐1992 9.1.1 には、
「その参照する実体は、その参照が現れた [CODE(SGML)[ps]]
の直後に続ける0個以上の完全な引数の列からなっていなければならない」
としています。[SAMP(SGML)["]] だけの実体が「完全な引数」
でないことは明らかですから、この例は'''不正'''です。

実はこの例は次のように書くのと同じことです。
[PRE[
<!ENTITY % q '"'>
<!ENTITY ent %q;entity value%q;>
]PRE]

こちらの例を見れば、「完全な引数」になっていないことはますます自明です。
[[実体値指定]]内の引数実体参照は宣言時ではなくそれを含む引数実体が参照された時に評価されることを思い出して下さい。

[4] 
[PRE[
<!ENTITY % e1 "'Q&#x26;#x26;#x26;A'">
<!ENTITY e2 %e1;>
]PRE]

後者の[[実体宣言]]の解釈を試みる。名前 [CODE(SGML)[e2]]
と、その直後の [CODE(SGML)[ps]] である [CODE(SGML)[s]]
である文字 [CODE(char)[[[SP]]]] まで読んだ。
ここで、引数実体参照 [SAMP(SGML)[%e1;]] を発見する。
この引数実体参照も、 [CODE(SGML)[ps]] として評価される。

引数実体 [SAMP(SGML)[e1]] の値を得るが、その[[引数表記]]は
[SAMP(SGML)["'Q&#x26;#x26;#x26;A'"]] である。
引数表記は両端が [CODE(SGML)[[[lit]]]] 又は
[CODE(SGML)[[[lita]]]] だが、ここでは前者である。
その間の部分は[[置換可能引数データ]]である。

置換可能引数データでは、[[文字参照]]と引数実体参照が解釈される。
[WEAK[XML では、構文上文字参照でも一般実体参照でもない文字 [CODE(XML)[&]] を書くことが出来ないが、そうだとしても一般実体参照はまだ認知されない・・・のかなあ。よくわからない。]]
従って、参照を置換した結果 [SAMP(SGML)['Q&#x26;#x26;A']] 
を得る。

結局、先の後者の実体宣言は 
[SAMP(SGML)[<!ENTITY e2 'Q&#x26;#x26;A'>]]
と書かれていたことになる。

同様の解釈 [WEAK[(さっきのよりずっと簡単。)]]
により、 [SAMP(SGML)[e2]] の[[置換文]]は
[SAMP(SGML)[Q&#x26;A]] であるとわかる。

文書実現値中で [SAMP(SGML)[&e2;]] と参照すると、
今度はその参照の位置で数値文字参照 [SAMP(SGML)[&#x26;]]
が評価され、結局その参照は[[文字データ]] [SAMP[Q&A]]
となる。

[5]
[PRE[
<!ENTITY % e1 "'Q&#x26;#x26;#x26;A'">
<!ENTITY % e2.5 "%e1;">
<!ENTITY e2 %e2.5;>
]PRE]

>>4 の例と大差がないように思えるこの例で、 [SAMP(SGML)[e2]]
の置換文を求める。

前例と同様の手順により、 [SAMP(SGML)[e2]] の解釈に必要な
[SAMP(SGML)[e2.5]] の置換文を求めることとなった。
[SAMP(SGML)[e2.5]] の引数表記の中身は引数実体参照
[SAMP(SGML)[%e1;]] である。前例同様、 [SAMP(SGML)[e1]]
の置換文は [SAMP(SGML)['Q&#x26;#x26;A']] である。
従って、 [SAMP(SGML)[<!ENTITY % e2.5 "'Q&#x26;#x26;A'">]]
と記述されていたとみなせる。

ここで、数値文字参照 [SAMP(SGML)[&#x26;#x26;]]
がまた評価され、置換文は [SAMP(SGML)['Q&#x26;A']] となる。
結局 [SAMP(SGML)[<!ENTITY e2 'Q&#x26;A'>]]
となり、文書実現値中で参照したときの置換文は
[SAMP(SGML)[Q&A]] となる。 
[WEAK[XML では、[[整形式]]エラーとなる。]]

・・・と思うのだが、試しに [[MSXML]] で読ませてみると、
[SAMP(SGML)[e2]] の実体宣言でえらーが出る。
「この場所ではスペースが許可されません」ハァ?

この解釈が間違っているのでしょうか?

([SAMP(XML)[<!ENTITY e2 '%e2.5;'>]] と宣言すれば、
なんとなく意図したようにはなります。)

[6]
[PRE[
<!ENTITY % AMP0 '&#x26;#x26;#x26;'>
<!ENTITY AMP0 '&#x26;#x26;#x26;'>
<!ENTITY AMPp "%AMP0;">
<!ENTITY AMP "&AMP0;">
]PRE]

文書実現値で [SAMP(SGML)[&AMP;]] と [SAMP(SGML)[&AMPp;]]
と参照することを考えます。

まず [SAMP(SGML)[&AMP;]] からです。その引数指定は一般実体
[SAMP(SGML)[AMP0]] への参照があるのですが、
実体宣言の段階ではまだ認知されていません。
一般実体 [SAMP(SGML)[AMP]] の置換文はそのまま 
[SAMP(SGML)[&AMP0;]] で、これが文書実現値中の参照の場所で評価されます。

一般実体・引数実体ともに、 [SAMP(SGML)[AMP0]]
の置換文は [SAMP(SGML)[&#x26;#x26;]] です。
[WEAK[(両実体の宣言の引数指定の解釈で1つずつ減ってます。)]]

一般実体 [SAMP(SGML)[AMP0]] を文書実現値中で評価した結果、
得られる文字データは [SAMP(SGML)[&#x26;]] となります。

さて、 [SAMP(SGML)[&AMPp;]] の場合です。
こちらは、一般実体 [SAMP(SGML)[AMPp]] の''実体宣言の時点で''、
その引数指定内の引数実体 [SAMP(SGML)[AMP0]] 
への参照が評価されているため、 [SAMP(SGML)[AMPp]]
の宣言は [SAMP(SGML)[<!ENTITY AMPp "&#x26;#x26;">]]
と同じことです。

また引数指定ですから、置換文は [SAMP(SGML)[&#x26;]]
になります。

これが文書実現値中で評価される時、得られる文字データは
[SAMP(SGML)[&]] になります。

[7] 頭の体操のような様相を呈してきました。。。
- [8] >>3 解釈の順序を考えれば二つの例は同等ではないです。
- [9] [CODE(ABNF)[[DFN[引数実体参照]] := [CODE(SGML)[[[pero]]]] [[文書型指定]] [[名前]] [[参照終了]] ;; (60)]]

[10] >>3 の「実体値指定内の引数実体参照は宣言時ではなくそれを含む引数実体が参照された時に評価される」というのは、何かの勘違いではないでしょうか。

[[実体文]](実体値指定)が[[引数表記]]([[実体値]])で記述されている場合、表記の中の引数実体参照は単に[[置換可能引数データ]]の文脈で解釈されます(JISX4151‐1992 表3, XML 4.4.5)。

従って、>>6 の例と同様、>>2 や >>3 の例での [SAMP(SGML)[%lt;]] や [SAMP(SGML)[%q;]] は [SAMP(SGML)[a]] の実体宣言の際に展開されてしまうので、[CODE(SGML)[ds]] や [CODE(SGML)[ps]] として認知されることはありません。結局、[SAMP(SGML)[%a;]] はどちらの例でも正当な [CODE(SGML)[ds]] として解釈され、一般実体 [SAMP(SGML)[ent]] が正しく宣言されたものと見なされます。
- [11] ''"WFC: In DTD" の意味 - XML Core 関連'' <http://www.satoshii.org/markup/xml/wfc-indtd>

[12]
XML では、[[内部部分集合]]の[[マーク宣言]]の内部に引数実体参照を入れることができません。
引数実体参照が使えるのは他のマーク宣言ど同位のところ (「地」の部分)
だけです。
([[整形式制約]] PEs in Internal Subset)

[[外部引数実体]]や[[外部部分集合実体]]ではこの制限はなく、
マーク宣言内に書くことができます。

ということは、内部部分集合で参照されている[[内部引数実体]]の中でも使えないということです。
[[条件区間]]と同じですね。

([[名無しさん]])

[13]
>>11 の文書は以前から気になっていた整形式制約 In DTD
のことを説明してくれています。

そこでは [[CDATA区間]]のためだろうという結論になっていますが、
それでも、 XML の構文では文字データ区間に引数実体参照が使える余地はありません。
ですから整形式制約として敢えて立てる必要性の説明にはならないと思います。
(本当はやはり不要で、歴史的なものではないかとにらんでいます。)

関係ありませんが、 SGML でも、
構文的には[[文書型宣言]]などで引数実体参照が認められながら、
本文でそれを取消す形になっています。
これはおそらく[[マーク宣言]]の[[空白]]にはすべて
[CODE(SGML)[[[ps]]]] を使いたかったからでしょう。

([[名無しさん]])


[14]
>>13 意表をついて、 [Q[DTD の中では使ってもいいよ]]という[Q[制約]]ではないかと思ったりしましたが、こういう解釈って駄目ですか?

XML の整形式・妥当性制約ってのは EBNF の生成規則で表現できないことを記述しているではないですか。で、マーク宣言内の引数実体参照もうまく表現できていないから・・・。

でももし本当にこういう意味だとしたら、
説明がよくなさすぎる。
([[名無しさん]] [WEAK[2004-06-06 03:27:37 +00:00]])



[49] 
[CITE[[[JIS X 4153:1998]][BR[]]文書スタイル意味指定言語(DSSSL)  解説]]
[TIME[2001-08-19T05:29:36.000Z]], [TIME[2023-11-19T13:04:37.509Z]] <http://www.y-adagio.com/public/standards/jis_dsssl/tutr.txt>


>  訳語選定に際しては,SGMLを規定しているJIS X 4151,SGMLの拡張規格であるJIS X 4155, 及びSGML関連規格であるJIS X 4171との整合を第一に配慮した。しかし次の用語などについては,その後関連分野で普及した訳語表記に従っている。
>
>  原語                           訳語           
>  ------------------------------------------------
>[SNIP[]]  
>  parameter entity               パラメタ実体   



