[1] [DFN[[RUBYB[公開識別子]@en[public identifier]]]]は、[[外部識別子]]の一種。
典型的には[[公的公開識別子]]が使われる。

* SGML における定義

[FIG(quote)[
[2]
>
:[RUBYB[公開識別子] [public identifier]]:[[公開文]]を[[識別]]する[[最小表記]]。
-備考1. [[文書]]中の公開識別子は、公的公開識別子として解釈可能としてもよい、
-備考2. システムは、公開識別子から[[システム識別子]]への変換に対して責任をもつ。
.[INS[([[JISX4151]]‐1992 定義 (82))]]

[6]
> [[公開テキスト]]又はほかの[[共有情報オブジェクト]]の[[識別子]]。
-備考 公開識別子は、通常は[[可視表現]]にも利用できる[[正規文字列]]として定義される。
この規格は、公開識別子の別の二つの[[等価表現]]、
つまり [[SGML公式公開識別子]]及び[[構造化名公開識別子]]を認識する。 [INS[([[JISX4172]]:1998 3.11)]]
]FIG]

* DSSSL における公開識別子

[32] 関連:
[CODE[writing-mode]],
[[ISO/IEC 10179の用字系]]

* XML における公開識別子

[21] [[XML]] では[[公開識別子]]は[[文書型宣言]]、[[実体宣言]]、[[記法宣言]]で使うことができます。

[22] [[文書型宣言]]と[[実体宣言]]では、[[公開識別子]]が記述されている場合、[[システム識別子]]も記述しなければなりません。
[[記法宣言]]では[[公開識別子]]単独で記述することができます。

** 仕様書

[REFS[
- [20] [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/#dt-pubid>
]REFS]

** 正規化

[23] [[公開識別子]]が[[一致]]するか調べる際には、予め[[空白]] ([CODE(XML)@en[[[S]]]]) を [CODE(char)[[[U+0020]]]]
に置き換え、先頭と末尾の[[空白]]を除去するという[[正規化]]を行わなければ[['''なりません''']] [SRC[>>20]]。

[24] [[Firefox]] の [CODE(DOMi)@en[[[DocumentType]]]] の [CODE(DOMa)@en[[[publicId]]]]
には[[正規化]]された後の値が現れます。 [TIME[2014-03-02T04:59:45.500Z]]

[26] [[名前付き文字参照]]の [[DTD]] を読み込むかの判定に関して、 [[Firefox]] は[[正規化]]しますが、
[[Chrome]] は[[正規化]]しません。 [TIME[2014-03-02T05:09:08.00Z]]

;; テスト用: <data:text/xml,<!DOCTYPE hoge PUBLIC "-//W3C//DTD XHTML 1.1//EN " "http://hoge/"%3E<hoge%3E&copy;</hoge%3E>

;; [29] [[HTMLの構文解析]]ではこの正規化に相当する処理は行われません。

** 処理

[11] 利用については、[[外部実体]]や[[記法宣言]]を参照してください。

[30] [[大文字]]と[[小文字]]について、特に区別しないというような規定はありません。

** メモ

[3] XML の場合:
-[CODE(ABNF)[[DFN[PubidLiteral]] = <"> *PubidChar <"> / "'" *(PubidChar - "'") "'" ;; [12] ]]
-[CODE(ABNF)[[DFN[PubidChar]] = %x0A / %x0D / %x20 / ALPHA / DIGIT / "-" / "'" / "(" / ")" / "+" / "," / "." / "/" / ":" / "=" / "?" / ";" / "!" / "*" / "#" / "@" / "$" / "_" / "%" ;; [13] ]]

[REFS[
- [27] [CITE@en[Character set "$xml10-5e:PubidChar"]] ([TIME[2015-01-10 22:06:57 +09:00]] 版) <http://chars.suikawiki.org/set/%24xml10-5e%3APubidChar>
]REFS]

[28] この文字集合は [[WebSGML]] で拡張された [[Special]]
と一致します。

[4] XML での公開識別子の定義は
<http://www.w3.org/TR/REC-xml#dt-pubid>
にあります。
-[[システム識別子]]に加えて、公開識別子も指定できる。
--[[記法宣言]]では公開識別子だけでもよい。
-公開識別子を、代替 [[URI]] を作るのに使ってもよい。
[WEAK[([[SGML]] でいう[[型録]]。)]]
-代替 URI を作れないときにはシステム識別子から作った URI
を使う。
-[[一致]]を試みる前に、[[正規化]]する。
--全ての[[空白]]の連続を、1つの [CODE(char)[[[SP]]]] にまとめる。
--最初と最後の空白の連続は削除する。

[5] [CODE(char)[[[TAB]]]] をかけないのに注意。

[6] 何も説明がないことから推察できるように、公開識別子 (のすべての構成要素)
は大文字・小文字を区別します。

@@ [15] [[XML情報集合]]では...

* HTML における公開識別子

[25] [[HTML]] では[[公開識別子]]の[[正規化]]は行われません。そのまま [CODE(DOMa)@en[[[publicId]]]]
[[属性]]に現れますし、[[DOCTYPEスイッチ]]でもそのまま比較されます。

* [CODE(DOMa)@en[publicId]] 属性 (DOM)

@@ [19] ...

* 公開識別子の欠落

[16] [[文書型宣言]]、[[実体宣言]]、[[記法宣言]]、[[連結型宣言]]、[[未展開実体参照情報項目]]のいずれにおいても、
[[公開識別子]]は指定されないことがあります。また、いずれにおいても[[空文字列]]を[[公開識別子]]として指定することができます。

[17] [[XML情報集合]]は[[未展開実体参照情報項目]]については[RUBYB[[[未知]]]@en[unknown]]となることを、
それ以外についても[RUBYB[[[無値]]]@en[no value]]となることを認めています。

[18] [[DOM Standard]] はこのうち [CODE(DOMi)@en[[[DocumentType]]]] しか定義していませんが、
値として [[null]] を認めていません。 [[HTML Living Standard]] および [[Webブラウザー]]は
[CODE(HTML)@en[[[DOCTYPE]]]] に[[公開識別子]]が指定されなかった場合、[[空文字列]]を
[CODE(DOMa)@en[[[publicId]]]] とします。

[14] [[DOM3]] は [CODE(DOMi)@en[[[DocumentType]]]] の
[CODE(DOMa)@en[[[publicId]]]] が [CODE(IDL)@en[[[null]]]]
になる可能性に言及していません。
[CODE(DOMi)@en[[[Entity]]]], [CODE(DOMi)@en[[[Notation]]]]
については [[null]] になり得るとしています。

* URL 表現

[31] 
[[公開識別子]]を [[URL]] として表現する手法として
[CODE[urn:publicid:[VAR[*]]]] がありました。

* メモ

- [7] [[Google]] で検索すると見つかる公開識別子の説明は、大抵は[[文書型宣言]]の説明の一部で、しかもみんなほとんど同じ内容で、かつ公開識別子と公式公開識別子の違いを理解していないとか、微妙に間違ったことを言っているとか、そういうのばっかです。寂しいことですな。
- [8] >>7 ちゃんと分かってる人は当然いるはずだし、実際日記とか ML とかでそれは明らかなんだけど、そういう人が解説を書いてないので。。。
- [9] 公開識別子の識別子としての機能を考えると、勝手な文字列ではなく、[[公式公開識別子]]又は [[URN]] を使用するのが望ましいでしょう。

[10] 公開識別子 [VAR[P]] で識別される[[実体文]] [VAR[S[SUB[1]]]] が
[PRE[
[VAR[...]]
<!ENTITY % p.mod PUBLIC "[VAR[P]]" "[VAR[S[SUB[2]]]]">
%p.mod;
[VAR[...]]
]PRE]
であるようなこと [WEAK[(つまり、公開識別子だけを追いかけると循環参照に見えるけど、システム識別子を追いかけるとそうではない場合)]] があります。

SGML や XML には、これを直接に禁止する規定はないと思いますけど、もし[[型録]]を使用していると実際に循環参照になってしまうでしょうから注意が必要です。

それに、仕様的に問題がないとしても意味的にどうかなあと思いませんか。