実体宣言

実体宣言 (SGML、XML)

[5] 実体宣言 (entity declaration) は、 実体宣言するマーク付け宣言でした。

SGML における実体宣言

[1]

参照を可能にするために、1つの実体SGML名を指定するマーク宣言。 Entity declaration。 (JIS X 4151‐1992 3. (116))

[2] 規格参照具象構文では、 <!ENTITY ent "EntityValue"> のような記述となります。

[11] SGML 文書実体で参照されるほとんどの実体は実体宣言で宣言されているものです。その例外は、文書型宣言外部部分集合とか、連結型宣言の外部部分集合とか、幾つかあるにはあります。

[15] 実体名の pero 辺りは認知の特例になっています。 本来 pero は文脈上の制約があって、 直後に名前文字などが続く場合のみ認知しますが、 ここでは特別に制約なしで区切子として認知します。また、 その直後の ps は必須です。これによって、 引数実体参照と区別しています。

[17] Web SGML では、外部引数実体記法名を指定することでDTDデータ実体を参照させることができます。 (K.4.10.2 参照)

同じ名前に対する複数個の実体宣言

[3] XML 仕様書 <http://www.w3.org/TR/REC-xml#sec-entity-decl> 曰く:

If the same entity is declared more than once, the first declaration encountered is binding; at user option, an XML processor may issue a warning if entities are declared multiple times.

(同じ実体が複数回宣言されていたなら、最初に現れた宣言が束縛される。 利用者の任意選択により、 XML処理系は実体が複数回宣言されたときに警告を出しても良い。)

実体宣言の優先順

[16]

  1. 1番目に活性状態になった連結型宣言部分集合の実体宣言
    1. 連結型宣言内部部分集合の実体宣言
    2. 連結型宣言の外部部分集合の実体宣言
  2. 2番目に活性状態になった〜(略) (JIS X 4151‐1992 11.1.4.1 参照。)
  3. (原始)文書型宣言部分集合の実体宣言
    1. 文書型宣言の内部部分集合の実体宣言
    2. 文書型宣言の外部部分集合の実体宣言

複数の文書型宣言間でどれが採用されるかは、 実体参照//対応する実体宣言を参照。

優先度の低い (無視される) 実体宣言の妥当性

[4] さて問題です。無視された実体宣言の実体値などに関する制約は課せられるのでしょうか?

とりあえず、構文的な制約は課せられると考えて間違いないでしょう。 ですから、 <!ENTITY ent "foo"><!ENTITY ent "&">致命的誤りとなるはずです。

[6] 非解析実体が参照されている場合: <!ENTITY ent "foo" NDATA defined-notation><!ENTITY ent "foo" NDATA undefined-notation>。 妥当性制約「記法が宣言されていること」<http://www.w3.org/TR/REC-xml#not-declared> は、 「The Name must match the declared name of a notation.」 (Name は宣言された記法の名前に一致しなければならない。) と述べています。状況についての言及はなく、構文についてのみの言及ですから、 この妥当性制約は無視される場合も有効と思われます。

続き (記法がらみ) は記法 (>>3)辺りへ。

[7] 文書全体の整形式性について、 <http://www.w3.org/TR/REC-xml#dt-wellformed> は、

  • 文書全体として Document に一致すること。
  • すべてのXML//整形式制約を満たすこと。
  • 直接または間接に参照しているすべての実体が整形式であること。

と言っています。無視されている実体 (であったであろうもの) が参照されていないことは明らかです。 (無視されていなくても、 文書中で参照されていなければ整形式でなくてもいいようです。)

[8] 実体についての制限のほとんどは置換文が対象だから、 無視された宣言や参照されていない実体の宣言はあんまり制約されないのかな。

[9] 実体参照//解決 (>>26)に言及がある仕様の修正は重要。この修正がないと、非解析実体への参照がないか無視された宣言や参照されていない実体の宣言もチェックしないといけなかった。

[10] >>9 しかし他にも問題はある。 XML 名前空間の仕様 <http://www.w3.org/XML/xml-names-19990114-errata#NE08> 曰く:

All other tokens in the document which are required, for XML 1.0 well-formedness, to match the XML production for Name, must match this specification's production for NCName.

(文書中の全ての他の (QName 以外の), XML 1.0 整形式性のために XML 生成規則 Name と一致する必要がある字句は、 (名前空間整形式であるためには) この仕様書の生成規則 NCName と一致しなければなりません。)

>>7 の1つめの整形式性条件 (構文一致) とこの規定により、 実体値中の一般実体参照も NCName である必要があります。

まあ、もともと一般実体参照以外の & をチェックしないといけないのですから、 大した手間ではないのですが。

実体値中の実体参照の名前だけではなく、 NDATA の後の記法名も影響されます。

メモ

[12] 2003-09-14 03:08:10 +00:00 名無しさん: <!ENTITY lt "&#x3C;"><!-- (正) --> <!-- ... --> <!ENTITY lt "なにか。"><!-- (誤) --> ってのは高々警告で済ませるべきものですよねぇ。今の Message::Markup::XML::Parser は致命的誤りにしちゃうんだけど。。。

[18] なんとなく書いてみたけど途中で面倒になって止めた図:

      mdo
       #
    'ENTITY'
       |
    +--+--+
    |     #
    r    ps
    |     |
    +---+-+
        |
    +--++---+
    |  #    #
    | pero rni
    |  |    |
    | +++   |
    | | |   |
    | r #   |
    | | ps  |
    | | |   |
    +-+-+---+
        |
 +<-r---+--+
 |         #
 |        name
 #         |<----------r------------------+
 +<-r------+--+                           |
 |            #                           |
 |           ps                           |
 #            |                           |
 +---+--------+-+--------+----------+     |
 |   #          #        #          #     |
 | 'CDATA'    'SYSTEM' 'PUBLIC'  keyword -+
 | 'SDATA'      |         |
 | 'PI'         |       +-+-+
 | 'STARTTAG'   |       |   #
 | 'ENDTAG'     |       r   ps
 | 'MS'         |       |   |
 | 'MD'         |       +-+-+
 |   |          |         |
 |   |          |       +-+-+
 |   |          |       |   #
 |   |          |       r publit
 |   |          |       |   |
 |   |          +-+-----+---+
 |   |            |
 |   |            +------+
 |   |            |      #
 |   |            |     ps
 |   |            |      |
 |   |            |      +---+
 |   |            |      |   #
 |   |            |      | syslit
 |   |            |      |   |
 |   |            |      |   +--+---+<-------------+
 |   |            |      |   |      #              |
 |   |            |      | +-+-+   ps              |
 |   |            |      | |   |    |              |
 |   |            |      | | (kwd)  |              |
 |   |            |<-----|-+   r    |              |
 |   |            |      |     |    |              |
 |   |            |      +<----+----+              |
 |   |            |      |                         |
 |   |            |      +-----+----+--+-------+    |
 |   |            |      |     #       #       #    |
 |   |            |      | 'SUBDOC' 'CDATA'   kwd   r
 |   |            |      |    |     'NDATA'    |    |
 |   #            |      |    |     'SDATA'    +----+
 |  ps            |      |    |       #
 |   #            |      |    |      ps
 +-+-+            |    |       #
   |              |    |      name
   |              |    |       |
   #              |    |     +-+--+
  paralit         |    |     |    #
   |              |    |     |   ps
   |          |    |     |    #
   |          |    |     |   dso
   |          |    |     |    #
   |          |    |     |  attrspecs
   |          |    |     |    #
   |          |    |     |   dsc
   |          |    |     |    #
   +---+------+----+-----+----+
       |
     +-+-+
     |   #
     |  ps
     |   |
     +-+-+
       #
      mdc

CDATA	ps paralit
SDATA
PI
STARTTAG
ENDTAG
MS
MD

SYSTEM	[ps syslit]
PUBLIC	[ps publit [ps syslit]]
SUBDOC

CDATA	name [data]
NDATA
SDATA

#	paralit

!ENTITY	(# / cdata / (system / public) [subdoc / cdata / ndata / sdata])