注: この文書では、XMLの名前空間バージョン1.1の最終ワーキング・ドラフト ("Last Call Working Draft": 2002年9月) で提案された変更点にも触れています。
第1回の記事では、World Wide Web Consortium (W3C) が自らXML名前空間を使用することによってどのように先例を確立したかを見ていきました。さらに第1回の記事では、この話題に関して、一貫性のある用語の使用についても述べました。そこで今回は、自分独自のXMLボキャブラリーをどのように確立するかという実用的な話題を取り上げましょう。
ある特定の名前空間に関連した要素の中に、別の名前空間の子要素や属性が含まれることがあります。1つの例を見てみましょう。たとえば、データそのものが5つの名前空間を利用し、すべてこのサンプル要素の外で宣言された接頭辞を使用しているとします。
<snac:delivery>
<dc:date>20020717</dc:date>
<snac:recipient>725577</snac:recipient>
<upc:upc1>0-30000-06410-8</upc:upc1>
<snac:size-each>
<snac:value>3</snac:value>
<wm:weight>imperial-ounce</wm:weight>
</snac:size-each>
<snac:quantity>48</snac:quantity>
<snac:invoice-price>
<snac:money-amount>1.54</snac:money-amount>
<fin:currency>us-dollar</fin:currency>
</snac:invoice-price>
</snac:delivery>
|
この例で、snac 名前空間の作成者は、他の団体組織によってまだ確立されていない要素だけを定義しています。その設計の中で、delivery 要素は日付、UPCコード、重量と寸法、通貨名に関して他の名前空間に依存しています。
他の方法として、以下のように、属性に名前空間を適用する方法もあります。
<snac:size-each value="3" wm:weight="imperial-ounce" /> |
さらに、XMLに組み込まれるサポートがより少なくなりますが、以下のようにテキスト・ストリングに1つの名前空間を適用することもできます。
<snac:size-each value="3" weight="wm:imperial-ounce" /> |
この例では、snac:size-each 要素が値 (value) 属性および重量 (weight) 属性を持つよう定義され、後者には、重量および寸法の標準単位からなる列挙されたwm ストリング・リスト内の1つのストリングが含まれます。XML Schemaには、ストリングを修飾名に制限したいときに使える便利なQNameというデータ型があります。(処理命令のターゲットや実体のような、名前を付けることのできる他のXML項目は、名前空間を使って名前を修飾できません。パーサーが規則をチェックするかどうかにかかわらず、そのような名前にはコロンを含められません。)
ここでのベスト・プラクティス は、一見よく似た用語を区別する、あるいは分離する手段として名前空間を使用することです。互いに関連した複数の要素についての情報を表す手段として名前空間を使うべきではありません。そうする代わりに、属性を使ってください。
たとえば、ある時、red:card、blue:card などすべてのcard 要素を扱おうとした人がいました。(本人のために、要素名は実際の名前から変えてあります。)これは名前空間の誤用です。なぜなら、この場合はさまざまなカードの間で共通するものがあるようですが、接頭辞は、さまざまなカードが互いにまったく関連しないことを表すべきです。色の部分は、属性にすべきでしょう。
厳密にあなたの組織の内部だけで使われる1つまたは複数のXMLボキャブラリーを開発する場合があるでしょう。もしボキャブラリーが1つだけであれば、名前空間を適用しないで済むかもしれません。しかしベスト・プラクティス としては、たとえ1つだけであっても、独自のボキャブラリーには名前空間を適用すべきです。その理由の1つは、新しいバージョンを将来導入する可能性があるということです。(データ処理に関して確実に言えることは、常に機能強化が求められるものだということです。)
名前空間の適用は簡単です。あなたが管理するドメイン・ネーム内の1つのURIを選択し、そのURIを、特定のXMLタグ・セットを対象とする名前空間URIにすると定義します。さまざまなタグを秩序立って使用しているなら、それぞれのタグに関する規則を定めた設計文書がお手元にあるでしょう。その設計文書の中の1文か2文を名前空間URIの定義にすることができます。設計と規則をXMLで表現したい場合には、XMLスキーマの作成を考慮してください。
URI管理のベスト・プラクティス は、ドメイン・ネームの中の名前を命名するとき、ちょうどネットワーク内のマシン名を決めるように、あるいはWeb URLの名前を決めるようにすることです。まず最初に、http://www.example.com/namespace/ やhttp://namespace.example.com/ のようなURLを予約します。これらは、あなたのドメイン・ネーム内のすべての名前空間URIのルートとなります。(ヒント: もしあなたの組織の情報システム部門がXMLを理解していないなら、単に "namespace" という名前のマシンをネットワーク上のノードとして要請し、そのマシンの完全修飾ドメイン・ネームを名前空間URIのルートとしてください。)いったんルート名が確立すれば、フィールドを次々と追加して、ボキャブラリー名とバージョン番号を指定することができます。
名前空間を使用すれば、プロジェクトを今すぐ開始できるとともに、後から修正や機能強化をする余地もあります。将来、新しいXML要素や属性が追加されるでしょう。複数のプロジェクトで使われるXMLがすべて増大していて、それらがあまり秩序立って管理されていない場合には、各プロジェクトに別個の名前空間を与えてください。たとえば、企業で新しい「部品表 (Bill Of Materials)」プロジェクトと「購買 (Procurement)」プロジェクトでXMLを使用したいと考えているなら、http://namespace.example.com/BOM/V1とhttp://namespace.example.com/Procurement/V1をそれぞれのURIとして指定できるでしょう。それぞれのボキャブラリーを定める2つのチームが、互いに共通する要素をいくつか使用したいと考えるなら、1つの名前空間に共通項目を含めることができるでしょう (これがベスト・プラクティス です)。もちろん、まったく別個に作業するのも自由です。さらに、バージョン1 (URIの "V1") ボキャブラリーでは以前の非XMLシステムの名前を使用し、"V2" ではまったく白紙の状態から別個の名前を使うという計画も可能です。
ここでのベスト・プラクティス は、ボキャブラリーが実質的に変化するたびに名前空間URIを変更することです。これには、古いボキャブラリーの厳密なスーパーセットを形成する新しい要素を追加する場合が含まれます。そのような方針のもとでは、どのバージョンに対してもスキーマ検証を実行できるだけでなく、最初の公開時にバージョンがなかったスキーマを改良してバージョンを付けることさえできます。
W3Cの『XML名前空間 勧告』によれば、識別子は単なるURIではなく「URI参照」にすることもできます。これらの違いはRFC 2396の第4部に説明されていますが、ベスト・プラクティス としては、通常のURIを使用すべきです。
URI参照 (および将来のIRI参照) は相対指定にすることが可能ですが、相対URIは名前空間では使用すべきではありません。W3Cの方針としては、何らかの枠組みや参照において解決する必要のないストリングとして名前空間URIを扱う方向に傾いているようです。URI参照では # 記号の後にフラグメント識別子を使用できます。しかしRFCは、フラグメントの使用をとくに素材の取得 (取り出し) だけに限定しています。第1回の記事で説明したように、名前空間URIの用途は取得ではありません。
独自のXMLボキャブラリーを文書化するとき、データを互いに交換する顧客、製造業者、その他のビジネス・パートナーのURIに言及する必要があるかもしれません。1つのベスト・プラクティス は、RFC 2606で定義されているように、文書の中でドメイン・ネームexample.com、example.net、およびexample.orgをサンプルとして使うことです。
W3Cは、XSLT変換プロセッサーが名前空間を認識して処理できることを求めています。XSLTを使用すれば、特定の構造 (スキーマ) のXMLから、構造が同じで一部 (またはすべての) 名前が変えられたXMLに変換することができます。もちろん、XSLTはXMLの構造を変えることもできます。名前を変更できるのと同様に、適用される名前空間も変更できます。これは、古いXMLから、名前空間の異なる新しいスキーマに変換しなければならない場合に役立ちます。とくに、古いXMLがデフォルト名前空間を使用していて、それを接頭辞付きの名前空間に変換したいような場合には、これが便利です。
XSLTによる名前変更の例をいくつか示しましょう。まず、名前空間を使用しない例を示し、それをもとに例を発展させて、違いを見ていきます。
たとえばあるXML文書をコピーして、入力に含まれるname_to_change (この名前を変更) というすべての要素を名前変更したい場合には、中心的なテンプレートは以下のようになるでしょう。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > <!-- 他のテンプレートが続く ... --> <xsl:template match="name_to_change"> <new_name> <!-- まず属性をコピーした後、子をコピーする --> <xsl:copy-of select="@*"/> <xsl:copy-of select="*"/> </new_name> </xsl:template> </xsl:stylesheet> |
上の例では、古い名前と新しい名前のどちらも修飾されない (名前空間が使われない) ことを想定しています。他の方法も可能です。
たとえばあるXML文書をコピーして、入力に含まれるname_to_change (この名前を変更) というすべての要素に名前空間を適用したい場合には、スタイルシート内で名前空間を宣言し、それをnew_name に関連付ける必要があります。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ourspace="http://www.example.com/namespace/data1" > <!-- 他のテンプレートが続く ... --> <xsl:template match="name_to_change"> <ourspace:new_name> <!-- まず属性をコピーした後、子をコピーする --> <xsl:copy-of select="@*"/> <xsl:copy-of select="*"/> </ourspace:new_name> </xsl:template> </xsl:stylesheet> |
今度は、古い名前は修飾されていませんが、少なくとも1つの要素が新しい名前空間 (ourspace 接頭辞) に含まれ、新しい名前が付きます (new_name は名前のローカル部分です)。
あるXML文書をコピーし、1つの要素の修飾名を別の修飾名に変更したい場合には、入力文書とスタイルシートの間で名前空間URIを照合する必要があります。以下の例では、入力のzz:name_to_change というすべての要素が出力ではourspace:new_name という名前になります (なお、zz は入力文書の中のxmlns宣言によって "http://example.com/namespace/orders" というURIに関連付けられています)。ここで、zz その他の接頭辞が入力の中で使用されているかどうかを、スタイルシートは認識する必要がありません。各文書 (入力とスタイルシート) の中の接頭辞を別々にURIに解決した後、URIを照合するからです。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:theirspace="http://example.com/namespace/orders" xmlns:ourspace="http://www.fictitious.com/namespace/data/V1" exclude-result-prefixes="theirspace"> <!-- 他のテンプレートが続く ... --> <xsl:template match="theirspace:name_to_change"> <ourspace:new_name> <!-- まず属性をコピーした後、子をコピーする --> <xsl:copy-of select="@*"/> <xsl:copy-of select="*"/> </ourspace:new_name> </xsl:template> </xsl:stylesheet> |
結果をクリーンアップするために、入力の名前空間をexclude-result-prefixes リストに指定しました。ここでは、その名前空間内のすべての要素 (および属性とキーワード・ストリング) が他の名前空間に名前変更されることを想定しています。つまり、結果の中でtheirspace を宣言する必要がありません。
『XSLT勧告』では、使用すべき接頭辞がたとえスタイルシートで指定されていても、XSLTプロセッサーは自分で加工した接頭辞を使用できることになっています。私の知っている限りでは、接頭辞を不必要に変えてしまうXSLTプロセッサーは存在しません (これは良いことです)。求められた接頭辞を実際に使用することによって、プロセッサーはベスト・プラクティスを支援します。
すでに述べたように、XSLTは名前空間を使って、スタイルシート内でのみ認識される名前をスタイルシート内のオブジェクトにつけることができるとともに、スタイルシートが作成する要素、属性、処理命令の名前を指定する機能も持っています。テンプレートの名前を付けることも可能で、それらを名前空間で修飾することもできますが、テンプレートの名前空間はXML文書の入力、出力のいずれにも影響しません。出力がXMLであれば、スタイルシートでのみ使われる名前空間に関してexclude-result-prefixesをスタイルシートで使うことにより、出力での名前空間宣言を防げます。たとえば、スタイルシートの中で<xsl:template name="system:max"> と<xsl:element name="fin:currency"> が適切なコンテンツとともに使用されるとします。xsl:element によって出力の中に要素が作成されますから、名前空間fin の宣言をXSLTプロセッサーに作成させる必要もあります。実際、宣言が必要とされる場合には、exclude-result-prefixesはそれを抑制しません。system 名前空間が厳密にテンプレート名として使われている場合には、exclude-result-prefixesを使用してこの名前空間を抑制できます。
- デベロッパーの生産性を高めるために、論理的で一貫した接頭辞の名前を確立する。
- すべての場所で接頭辞を使用する。または、少なくとも、エンド・ユーザーに配信される実際のコンテンツを除くすべての項目で接頭辞を使用する。
- 独自のボキャブラリーに名前空間を適用する (たとえボキャブラリーが1つしかない場合でも)。
- 一見してよく似た用語を区別する、あるいは分離する手段として名前空間を使う。
- 設計中の2つのボキャブラリーに含まれる一部の要素が共通している場合、1つの名前空間 (たとえば元の2つとは別個の名前空間) に共通項目を含める。
- URIにはHTTP URLを使用し、フラグメント識別子は使わない。
- ドメイン・ネームの中の名前を命名するとき、ちょうどネットワーク内のマシン名を決めるように、あるいはWeb URLの名前を決めるようにする。
- ボキャブラリーが実質的に変化するたびに名前空間URIを変更する。これには、古いボキャブラリーの厳密なスーパーセットを形成する新しい要素を追加する場合が含まれる。
- 可能であれば、システム内のすべてのXML文書で、1つの名前空間に対して1つの接頭辞を使用する。
- それぞれの文書内で名前空間を明示的に宣言することにより、想定や依存関係を抑止する。
- 可能であれば、すべての名前空間宣言を文書要素の開始タグに含める。
- W3Cによって定義された要素と属性に関しては、W3Cの使用する接頭辞を使う。
- 要素の内容が特定の自然言語に従うことを宣言するために、
xml:lang属性を使用する。
- 開始タグについて話し合うとき、「名前空間宣言」と「属性」をよく区別する。
- 「名前空間名 (namespace name)」という言い方を避ける。または、意味が明確な場合にのみ使用する。
- 文書の中でドメイン・ネームexample.com、example.net、およびexample.orgをサンプルとして使う。
- David Marston氏による前回の記事XML名前空間の使用を計画する: 第1回で、XML名前空間の利点を理解し、W3C標準のXMLフォーマットやツールでXML名前空間をどのように使用できるかを学習してください。
- W3CのXML名前空間1.0勧告は、標準を確定しています。
- W3CのXML Schema勧告は、Primer、Structures、およびDatatypes の3つの部分からなります。
- W3Cは、識別子に関する体系的な原則を開発しています。
-
XInclude はW3Cの勧告になろうとしています。
-
W3CのXML Information Setの勧告は、XMLツリー構造の部分の意味を識別する抽象的な設計です。
- "現実世界でのXML Schema" は、命名のアイデアを提供します (developerWorks、2002年1月)。
- Christina Lauの "XML and WebSphere Studio Application Developer" の第6回では、スキーマの中での名前空間の使用法についての指導を行っています。
- W3CのボキャブラリーであるMathML と、OASIS Technical CommitteeによるDirectory Services Markup Language (DSML) についてさらに調べてください。
- 最新の"XPointer xmlns() Scheme" のドラフトで、名前空間を宣言するための若干異なる方法を調べてください。
- URIの一般構文であるRFC 2396 には、URIの詳細が豊富に説明されています。
-
developerWorks XMLゾーンで、さらにXMLの参考文献を調べてください。
-
XMLおよびその関連テクノロジーのIBM Certified Developer になる方法をお調べください。