第25回 外部実体における統一資源識別子(URI) Page 2

川俣 晶
株式会社ピーデー
2004/9/8

統一資源識別子(URI)

 さて、次はいよいよお待ちかね。URIを使ううえで極めて悩ましい問題の1つ、相対URIの話題に入る。通常のURIは、例えば「http://www.autumn.org/index.html」というような表記になる。あるリソースを指定するのに十分な情報がすべて詰まっていて、この文字列を指定すれば世界中のどこからでも同じページを開くことができる。これを絶対URIという。しかし、常にURI指定は絶対URIでなければならないという理由はない。例えば、上記リソースの内部から、<img src="autumn003.jpg" />というような表記で画像を参照することができるが、画像を指定する「autumn003.jpg」という表記もURIの一種であり、相対URIと呼ばれる。この「autumn003.jpg」という表記は、それだけを取り出してほかの場所に持っていくと、もはや特定のリソースを示すという機能性を発揮しない。ここで、「http://www.autumn.org/index.html」というリソースの中で「autumn003.jpg」という相対URIを指定するということは、「http://www.autumn.org/index.html」を基準点として、「http://www.autumn.org/autumn003.jpg」という絶対URIに相当するリソースがあると判断される。しかし、基準点はさまざまな理由により変化してしまう場合があり、また意図的に変化させる場合もある。そのため、相対URIは1文字たりとも表記を変えなくても、同じリソースを指し示さない可能性があり、扱いが難しい。XML勧告でも、実体を参照するためにURIを活用する以上、同じ問題がつきまとう。

 では本文を読んでいこう。(編集部注:前ページで掲載した原文とその訳を再度掲載する)

[Definition: The SystemLiteral is called the entity's system identifier. It is meant to be converted to a URI reference (as defined in [IETF RFC 2396], updated by [IETF RFC 2732]), as part of the process of dereferencing it to obtain input for the XML processor to construct the entity's replacement text.] It is an error for a fragment identifier (beginning with a # character) to be part of a system identifier. Unless otherwise provided by information outside the scope of this specification (e.g. a special XML element type defined by a particular DTD, or a processing instruction defined by a particular application specification), relative URIs are relative to the location of the resource within which the entity declaration occurs. This is defined to be the external entity containing the '<' which starts the declaration, at the point when it is parsed as a declaration. A URI might thus be relative to the document entity, to the entity containing the external DTD subset, or to some other external parameter entity. Attempts to retrieve the resource identified by a URI MAY be redirected at the parser level (for example, in an entity resolver) or below (at the protocol level, for example, via an HTTP Location: header). In the absence of additional information outside the scope of this specification within the resource, the base URI of a resource is always the URI of the actual resource returned. In other words, it is the URI of the resource retrieved after all redirection has occurred.

[定義:SystemLiteralを、実体のシステム識別子(system identifier)と呼ぶ。XMLプロセサが、実体の置換テキストを生成するには、入力を必要とするが、入力を得るためにシステム識別子を参照する処理の一部として、統一資源識別子(URI)参照([IETF RFC 2396]で定義され、[IETF RFC 2732]で改訂された。) に変換してから参照することが意図されている。] 素片識別子(#文字で始まるもの。)がシステム識別子に含まれることは誤りとする。この規格の適用範囲外の情報(例えば、ある特定のDTDの特別なXML要素または特定の応用プログラムの仕様によって定義された処理命令)によって上書きされない限り、相対的な統一資源識別子(URI)は、その実体の位置、すなわち、その実体宣言が現れる資源に相対的とする。実体宣言が現れる資源とは、この実体宣言を宣言として構文解析した時点で、先頭の'<'を含む外部実体とする。したがって、統一資源識別子(URI)は、文書実体外部DTDサブセットを含む実体・なんらかの外部パラメタ実体に対して相対的とする。統一資源識別子(URI)によって特定される資源を得ようとするとき、パーサのレベルでリダイレクトされてもよく(例えば、実体リゾルバ)、下位プロトコルのレベル(例えば、HTTPのLocation:ヘッダ)によってリダイレクトされてもよい。この規格の適用範囲外の付加的な情報が資源の中に存在しない限り必ず、リソースの基底統一資源識別子(URI)は実際に返されたリソースの統一資源識別子(URI)とする。言い換えれば、すべてのリダイレクションが起こった後で得られるリソースの統一資源識別子(URI)とする。

 次の文章(「この規格の適用範囲外の情報〜」で始まる文章)は後半から読んでいこう。後半では、相対URIの基準点は、実体宣言が現れる資源にあるという。例えば、実体宣言が「http://www.atmarkit.co.jp/sample.xml」というリソースに含まれていて、それが「sample.ent」という相対URIを指定しているとする。すると、この相対URIは、「http://www.atmarkit.co.jp/sample.ent」という絶対URIが示す位置を指し示すことになる。このような解釈の例外事項が文章の前半に述べられている。それは、基準点がこの規格の適用範囲外の情報による上書きである。ちなみに、W3Cには「XML Base」という相対URIの基準点を指定する勧告があるが、これはここでいう上書きの機能を持たないことに注意が必要である。理由は、「XML Base」の「C Impacts on Other Standards (Non-Normative)」に書かれているとおり、実体宣言は「XML Base」の属性が効力を発揮する範囲外に記述されるためである。

 次の文章に進もう。実体宣言は<!ENTITYで書き始めるので、必ず'<'が先頭に含まれることになる。その1文字が含まれる資源が実体宣言が現れる資源であると規定している。ここでわざわざそのことを規定しなければならないのは、パラメタ実体を使えば、1つの実体宣言が複数の資源に含まれる文字列によって構成される可能性があるためである。

 例えば、リソース「http://sample-a/sample-a.dtd」に以下のような実体宣言があったとする。

<!ENTITY %sample;>

 そして、リソース「http://sample-b/sample-b.dtd」に以下のようなパラメタ実体宣言があったとする。

<!ENTITY % sample SYSTEM "sample.ent" >

 この2つを併用したとき、「sample.ent」という相対URIは、果たして「http://sample-a/sample.ent」になるのだろうか。それとも「http://sample-b/sample.ent」になるのだろうか。この文章の規定により、実体宣言の先頭の「<」を含む資源(実体宣言の「一部」を構成するパラメタ実体を含む資源ではない)ということになるので、「http://sample-a/sample.ent」という解釈になる。

 次に進もう。ここでは3種類の資源が、相対URIの基準点になる可能性が示されている。ここで注意が必要なのは外部パラメタ実体だろう。上の例ではパラメタ実体を含む資源が基準点にならない例を示したが、基準点にならなかった理由は実体宣言の最初の「<」が含まれていなかったことが理由なのであって、パラメタ実体だから基準点にならないというわけではないのである。つまり、パラメタ実体の中に実体宣言の最初の「<」が含まれていれば、そのパラメタ実体を含む資源が基準点になり得るということである。

 これで相対URIの話題はひとまず終わりである。次の文章は別の話題に進む。

URIのリダイレクト

 次の文章は、URIで指定された場所とは異なる場所から資源を取得してよい(MAY)ことを示している。このような機能は、いろいろな意味で有益である。例えば、ある外部実体に1日100万回アクセスするシステムがあったとき、その外部実体が低速回線で接続されたサーバ上に置かれていたとすると、低速回線の帯域は外部実体へのアクセスだけであふれてしまうかもしれない。そのような場合には、同じ内容の資源を置いたLAN上のサーバにリダイレクトしてやれば、回線をあふれさせることを回避できる。また、資源の置き場所を移転した場合など、新しい置き場所へのリダイレクト情報を入れることができれば、互換性を維持しつつ移転が実現できる。

 さて、リダイレクトの方法として、2つのやり方が示されている。1つは、パーサが実体リゾルバによってリダイレクトする方法である。パーサとは、XML勧告の中ではXMLプロセサと表記されているものと事実上同じと考えてよいだろう。つまり、文字の並びとしてのXML文書を受け取って、その構造を「解析するもの」(parser=パーサ)である。実体リゾルバとは指定された資源が実際にどこにあるのかを指定するメカニズムで、応用プログラム側で作成して、パーサに指定するものである。

 以下は、ある程度プログラミングの心得のある読者にプログラミング上のヒントを示すために補足する。例えば、.NET Frameworkのクラスライブラリであれば、System.Xml.XmlResolverクラスを継承したクラスを実体リゾルバとして機能させることができる。このクラスを継承し、独自のリダイレクトを行うクラスを作成する。そのクラスのインスタンスを、DOMを実装しているSystem.Xml.XmlDocumentクラスのXmlResolvberプロパティに代入してやれば、リダイレクトが行われる。

 もう1つのやり方は、HTTP(Hypertext Transfer Protocol)で定義されたリダイレクト機能を使用する方法である。Location:ヘッダとは、HTTPでリダイレクトを行うために使用される機能である。ここでは詳しい説明は行わないが、XML勧告ではこのようなリダイレクトの機能は実体の参照時に有効であると認めている。

 次の文章は前半が例外規定であるので、後半から読んでいこう。後半では、基底統一資源識別子(URI)という言葉が出てくるが、これが相対URIの基準点である。これは、実際に返されたリソースのURIであるとしている。例えば「http://sample-a/sample-a.ent」というURIを持つ外部実体にアクセスした際に、それが「http://sample-b/sample-b.ent」というURIにリダイレクトされたとしよう。この資源の基準点は、リダイレクトされた後のURI、「http://sample-b/sample-b.ent」となるわけである。さて、文章の前半は、この規格の適用範囲外の付加的な情報が資源の中に存在する場合は、この規定とは異なるルールで基準点が決まる場合があり得ることを示している。

 さて、次がこの段落の最後の文である。これは上の文章の分かりやすいいい換えである。

2/4

 Index
やさしく読む「XML 1.0勧告」 第25回
外部実体における統一資源識別子(URI)
  Page 1
・外部実体の後半
・システム識別子の定義
Page 2
・統一資源識別子(URI)
・URIのリダイレクト
  Page 3
・URIにおける文字の別扱い
・文字の別扱いの手順
  Page 4
・公開識別子(Public identifier)の定義
・外部実体宣言の例


連載 やさしく読む「XML 1.0勧告」


XML & SOA フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

HTML5+UX 記事ランキング

本日月間