XMLスキーマの使用法の基本: エレメントの定義

XML文書の構造定義のためにDTDの代わりにXMLスキーマを使用する

新しい XML スキーマの体系が、まもなく W3C 勧告になろうとしています。これは、XML 文書用の豊富な文法的構造を提供し、これまでの DTD の限界を克服することを目的とするものです (DTD の限界の囲みを参照してください)。この記事では、スキーマの柔軟性を例示し、XML スキーマの体系において XML 文書の最も基礎的な構成ブロックであるエレメントの定義方法を示します。

Ashvin Radiya (ashvin@avantsoft.com), President and CTO, AvantSoft, Inc.

Ashvin Radiya 氏は、 AvantSoft, Inc. の創設者であり、社長です。CTO として、最新の Java プログラミングおよび関連テクノロジーに関する AvantSoft トレーニング・コースの開発と普及に率先してきました。また、Fortune 100 の企業との戦略的提携を築き、その管理に携わっています。Ashvin 氏は、産業界、大学関係、そして専門分野についての幅広い経験を有しています。彼は オースチンの IBM において、先進的な CORBA ベースの分散型オブジェクト指向プロダクトの仕事に携わりました。モバイル・コマース、XML、Java、JavaBeans、Enterprise JavaBeans コンポーネント、InfoBus、セキュリティー、CORBA、および分散型オブジェクト指向プログラミングの分野で、高度な知識と専門技術を有しています。Ashvin 氏はシラキュース大学より、コンピューター・サイエンスの博士号を授与されました。Ashvin Radiya 氏の連絡先は、ashvin@avantsoft.com です。



Vibha Dixit (vibha@avantsoft.com), CEO, AvantSoft, Inc.

Vibha Dixit 氏は、AvantSoft, Inc. において、ビジネス開発マネージャーおよび科学技術者としてかぎとなる役割を果たしています。彼女はビジネス計画、戦略的提携の管理、新規顧客の獲得、販売およびマーケティングの責任者です。また、モバイル・コマース、XML、および Java テクノロジーの分野における AvantSoft 社のテクノロジー目標と方向性の定義付けにも積極的に関与しています。Vibha 氏は、ビジネス管理におけるユニークな経験を持ち、コンピューター・テクノロジーにおいても強力な実務経験を有しています。AvantSoft 社に加わる以前は、IBM サンタ・テレサ研究所で分散トランザクション型オブジェクト・ミドルウェアの仕事に携わっていました。オハイオ・スーパーコンピューター・センターでは、マルチ・コンピューター用のオペレーティング・システムの設計と開発に参加しました。Vibha 氏はオハイオ州立大学より、コンピューター・サイエンスの博士号を授与されました。さらに、南部メソジスト大学で上級経営管理学修士課程を修了しています。Vibha Dixit 氏の連絡先は、vibha@avantsoft.com です。



2000年 8月 01日

XML スキーマは DTD よりもはるかに強力なものです。XML スキーマの能力を例示するために、最初の 3 つのリストでは、エレメントの各種の表現方法を簡単に比較します。リスト 1 は XML 文書の抜粋です。リスト 2 はこれら 2 つのエレメントの DTD 構文による宣言であり、リスト 3 はそれに対応する XML スキーマ構文です。リスト 3 の構文は XML の構文と同じであることに注目できます。スキーマを見ることによって、妥当性検査パーサーは、エレメントInvoiceNo が正の整数であり、エレメントProductID が A ~ Z の 1 文字に 6 桁の数字が続いたものであることを検査することができます。対照的に、DTD を参照する妥当性検査パーサーは、これらのエレメントがストリングで表現されていることを検査できるにすぎません。

リスト 1: XML 文書の一部
<InvoiceNo>123456789</InvoiceNo>
<ProductID>J123456</ProductID>
リスト 2: リスト 1 のエレメントを記述した DTD
<!ELEMENT InvoiceNo (#PCDATA)>
<!ELEMENT ProductID (#PCDATA)>
リスト 3: リスト 1 のエレメントを記述した XML スキーマ
<element name='InvoiceNo' type='positive-integer'/>
<element name='ProductID' type='ProductCode'/>
<simpleType name='ProductCode' base='string'>
  <pattern value='[A-Z]{1}d{6}'/>
</simpleType>

XML スキーマにおけるネームスペースの使用

様々な人と協力して仕事を行う世界では、ある人が他のグループから受け取った文書を処理することがあり、他のグループでは自分とは別の方法でデータ・エレメントを表現することを望むことがあります。さらに、一つの文書の中で、別のグループが作成したエレメントで同じ名前を持つものを区別して参照する必要があるかもしれません。では、同じ名前の別々の定義をどのように区別することができるでしょうか? XML スキーマでは、ネームスペースを使ってそれらの定義を区別します。

DTD の限界

DTD は、構造化された情報を記述するためのメカニズムとして 20 年にわたり SGML および HTML 開発者に貢献してきましたが、XML スキーマに比べると DTD には厳しい制約があります。

DTD は、エレメントが次の 3 つのいずれかから成ることを求めます。

  • テキスト・ストリング
  • 別の子エレメントが混在しているテキスト・ストリング
  • 子エレメントの集合

DTD は XML 構文を持たず、タイプやネームスペースに対して限られたサポートしか提供しません。

一つの XML スキーマでは、エレメント、タイプ、属性、属性グループの名前など、一連の新しい名前を定義します。それらの定義と宣言はスキーマ内に記述されます。リスト 3 ではInvoiceNoProductID、およびProductCode として名前を定義しています。

一つのスキーマ内で定義された名前は、そのターゲット・ネームスペース に属していると言います。ネームスペース自体は、固定の名前を持ちます。この名前は任意に決めることができます。ネームスペースの名前は URL 構文に従います。たとえば、リスト 3 に抜粋されたスキーマのネームスペースの名前は、http://www.SampleStore.com/Account と設定することができます。

ネームスペースの構文は、誤解しやすいものかもしれません。ネームスペース名はhttp:// で始まりますが、その URL にあるスキーマ定義を含むファイルを指すものではありません。実際、URLhttp://www.SampleStore.com/Account は、どのファイルを指すものでもなく、ネームスペースに割り当てられた名前を表しているだけです。

スキーマ内の定義と宣言は、他のネームスペースに属する名前を指していることもあります。この記事では、それらのネームスペースをソース・ネームスペース と呼びます。つまりそれぞれのスキーマには、1 つのターゲット・ネームスペースと、おそらく多くのソース・ネームスペースがあることになり、スキーマ内のすべての名前は何らかのネームスペースに属します。ネームスペースの名前はかなり長くなることがありますが、XML スキーマ文書内のxmlns 宣言の構文によって短縮形を指定します。これからリスト 4 に示されたスキーマ例にネームスペースを追加してゆくことによって、これらの概念を示すことにします。

リスト 4: ターゲットおよびソース・ネームスペース
<!--XML Schema fragment in file schema1.xsd-->

<xsd:schema targetNamespace='http://www.SampleStore.com/Account'
      xmlns:xsd='http://www.w3.org/1999/XMLSchema'
      xmlns:ACC= 'http://www.SampleStore.com/Account'>
<xsd:element name='InvoiceNo' type='xsd:positive-integer'/>
<xsd:element name='ProductID' type='ACC:ProductCode'/>
<xsd:simpleType name='ProductCode' base='xsd:string'>
  <xsd:pattern value='[A-Z]{1}d{6}'/>
</xsd:simpleType>

リスト 4 の XML スキーマでは、targetNamespace の名前はhttp://www.SampleStore.com/Account であり、これにはInvoiceNoProductID、およびProductCode という名前が含まれています。schemaelementsimpleTypepatternstring、およびpositive-integer という名前は、ソース・ネームスペースのhttp://www.w3.org/1999/XMLSchema に属しています。このネームスペースには、xmlns 宣言によってxsd という短縮系が与えられています。別名として割り当てるxsd については、特に決まりはありません。どんな名前でも選択できます。便宜上、またこの記事の残りの部分を簡単にするため、ネームスペースhttp://www.w3.org/1999/XMLSchema を指すものとしてxsd を使用し、一部のコードではxsd の修飾も省きます。この例では、targetNamespace が、ソース・ネームスペースの 1 つにもなっていますが、これは、ProductCode という名前が、他の名前の定義に使用されているからです。

図 1: リスト 4 のネームスペース
リスト 4 のネームスペース

リスト 4 のスキーマ (一部) では、ソース・スキーマ・ファイルのロケーションを指定する必要はありません。"スキーマのスキーマ" であるhttp://www.w3.org/1999/XMLSchema については、そのロケーションはよく知られているので、指定する必要はありません。ソース・ネームスペースのhttp://www.SampleStore.com/Account については、それが今まさにこのファイルで定義しようとしているターゲット・ネームスペースにもなっているので、ロケーションを指定する必要はありません。スキーマのロケーションの指定方法とデフォルトのネームスペースの使用法についてさらによく理解するため、リスト 5 の例の拡張部分を考慮しましょう。

リスト 5: 複数のソース・ネームスペース、ネームスペースのインポート
<!--XML Schema fragment in file schema1.xsd-->
<schema targetNamespace='http://www.SampleStore.com/Account'
      xmlns='http://www.w3.org/1999/XMLSchema'
      xmlns:ACC= 'http://www.SampleStore.com/Account'
      xmlns:PART= 'http://www.PartnerStore.com/PartsCatalog'>
<import namespace='http://www.PartnerStore.com/PartsCatalog'
            schemaLocation='http://www.ProductStandards.org/repository/alpha.xsd'/>
<element name='InvoiceNo' type='positive-integer'/>
<element name='ProductID' type='ACC:ProductCode'/>
<simpleType name='ProductCode' base='string'>
  <pattern value='[A-Z]{1}d{6}'/>
</simpleType>
<element name='stickyGlue' type='PART:SuperGlueType'/>

リスト 5 には、さらにもう 1 つのネームスペースへの参照が加わっています。それはhttp://www.PartnerStore.com/PartsCatalog です。このネームスペースは、targetNamespace とも、標準ネームスペースとも異なります。結果として、それはimport 宣言エレメントを使用してインポートしなければならず、そのschemaLocation 属性は、スキーマを含むファイルのロケーションを指定します。デフォルトのネームスペースはhttp://www.w3.org/1999/XMLSchema であり、そのxmlns 宣言には短縮形の名前がありません。これによってschemaelement といった修飾なしの名前はすべて、デフォルトのネームスペースであるhttp://www.w3.org/1999/XMLSchema に属すことになります。スキーマで 1 つのネームスペースからの名前を複数参照している場合、それをデフォルトのネームスペースとして指定する方が便利です。

XML インスタンス文書で、複数のスキーマで定義された複数のネームスペースに属するエレメントの名前を参照することがあります。ネームスペースの名前を参照し、その名前の短縮形を宣言するためには、xmlns 宣言を使用します。XML スキーマ・インスタンスのネームスペースに属するschemaLocation 属性を使用して、ファイルのロケーションを指定します。この属性は、前述の例のxsd ネームスペースの 同じ名前の属性schemaLocation とは異なることに注意してください。

リスト 6: 複数のスキーマの複数のネームスペース名の使用
<?xml version="1.0"?>
<ACC:rootElement xmlns:ACC='http://www.SampleStore.com/Account'
      xmlns:PART='http://www.PartnerStore.com/PartsCatalog'
      xmlns:xsi='http://www.w3.org/1999/XMLSchema-instance'
      xsi:schemaLocation='http://www.PartnerStore.com/PartsCatalog
                          http://www.ProductStandards.org/repository/alpha.xsd
                          http://www.SampleStore.com/Account
                          http://www.SampleStore.com/repository/schema1.xsd'>
<ACC:InvoiceNo>123456789</ACC:InvoiceNo>
図 2: リスト 5 および 6 のネームスペース
リスト 5 および 6 のネームスペース

エレメントの定義

エレメントを定義するということは、その名前と内容モデルを定義することです。XML スキーマでは、エレメントの内容モデルはそのタイプ別に定義されます。それで、XML 文書内のインスタンス・エレメントは、そのスキーマで定義されているタイプに一致した値だけをとることができます。

単純タイプ

XML スキーマ仕様では、値用に単純タイプをいくつか定義しています。

タイプは単純か複合のいずれかです。単純タイプは、その値にエレメントや属性を含めることはできません。複合タイプでは、他のエレメント内の組み込みエレメントの効果を出したり、属性をエレメントに関連付けることができます。この記事の中のここまでの例は、ユーザーの定義した単純タイプです (ProductCode を参照)。XML スキーマ仕様には、事前に定義された単純タイプも含まれています (単純タイプの囲みを参照してください)。派生的単純タイプ は、基本タイプに値が限定されます。たとえば、派生的単純タイプであるProductCode の値は、基本タイプstring の値のサブセットになります。

ネストしていない単純なエレメントは単純タイプになる

属性や他のエレメントを含まないエレメントは、事前に定義された単純タイプまたはユーザー定義の単純タイプとして定義することができます。この例としては、stringintegerdecimaltimeProductCode などがあります。

リスト 7: エレメント用のいくつかの単純タイプ
<element name='age' type='integer'/>
<element name='price' type='decimal'/>

属性を持つエレメントは必ず複合タイプになる

さて、リスト 7 の単純エレメントprice に、属性currency を追加することは可能でしょうか。実はそれはできません。単純タイプのエレメントは属性を持つことができないのです。属性を追加したいなら、price を複合タイプとして定義しなければなりません。リスト 8 の例では、いわゆる無名タイプ と呼ばれるものを定義しました。この場合、複合タイプには明示的な名前が与えられていません。言い換えると、complexType エレメントのname 属性は定義されないということです。

リスト 8: 複合エレメント・タイプ
<element name='price'>
  <complexType base='decimal' derivedBy='extension'>
    <attribute name='currency' type='string'/>
  </complexType>
</element>
<!-- In XML instance document, we can write: <price currency='US'>45.50</price> -->

他のエレメントを組み込んでいるエレメントは必ず複合タイプになる

XML 文書では、エレメントの下位に他のエレメントを含むことができます。この要件は DTD では直接的に表現されます。XML スキーマでは、代わりに type 属性を持つエレメントを定義し、その type 属性が他のエレメントや属性の宣言を指すようにすることができます。簡単な例として、表 1 をご覧ください。

表 1: DTD と XML スキーマでの複合データ・タイプの比較
XML 文書
<Book>
<Title>Cool XML<Title>
<Author>Cool Guy</Author>
</Book>
DTD
<!ELEMENT Book (Title, Author)>
<!ELEMENT Title (#PCDATA)>
<!ELEMENT Author (#PCDATA)>
XML スキーマ
<element name='Book' type='BookType'/>
<complexType name='BookType'>
<element name='Title' type='string'/>
<element name='Author' type='string'/>
</complexType>

表 1 の XML コードは DTD と XML スキーマの両方に従っていますが、それらの間には大きな違いがあります。DTD ではすべてのエレメントがグローバルですが、表中の XML スキーマでは、TitleAuthor がローカルに定義されています。それらは、エレメントBook の中でのみ出現可能です。DTD の宣言の作用を XML スキーマで厳密に再現しようとすれば、リスト 9に示されているように、エレメントTitleAuthor がグローバルな有効範囲を持つ必要があります。エレメントelementref 属性により、すでに宣言されているエレメントを参照することが可能になります。

リスト 9: グローバルな単純タイプで定義された複合タイプ
<element name='Title' type='string'/>
<element name='Author' type='string'/>
<element name='Book' type='BookType'/>
<complexType name='BookType'>
   <element ref='Title'/>
   <element ref='Author'/>
</complexType>

表 1リスト 9 の例では、BookType はグローバルであり、他のエレメントを宣言するために使用することができます。対称的に、リスト 10 では、このタイプはエレメントBook の定義に対してローカルなものとし、またそのタイプは無名です。表 1 の XML 文書は、表 1、リスト 9、およびリスト 10 の 3 つのスキーマすべてに一致していることに注目できます。

リスト 10:BookType をローカル・タイプとして隠す
<element name='Title' type='string'/>
<element name='Author' type='string'/>
<element name='Book'>
   <complexType>
      <element ref='Title'/>
      <element ref='Author'/>
   </complexType>
</element>

エレメントに関する洗練された制約の表現

XML スキーマは、エレメントの内容モデルの制約を表現するために、DTD より優れた柔軟性を持っています。最も簡単なレベルでは、DTD の場合と同様に、属性をエレメント宣言に関連付けることができ、与えられたエレメントのセットから、1 回だけ (1)、0 回以上 (*)、または 1 回以上 (+)、エレメントの順序列がその中で出現できることを示すことができます。XML スキーマでは、さらに制約を表現する付加的な方法があります。たとえば、エレメントelementminOccurs およびmaxOccurs 属性を使用したり、choicegroup、およびall エレメントを使用することができます。

リスト 11: エレメント・タイプでの制約の表現
<element name='Title' type='string'/>
<element name='Author' type='string'/>
<element name='Book'>
  <complexType>
    <element ref='Title' minOccurs='0'/>
    <element ref='Author' maxOccurs='2'/>
  </complexType>
</element>

リスト 11 では、 Book の中でのTitle の出現はオプションとなります (DTD の '?' と同じ)。しかし、リスト 11 ではさらに、エレメントBook の中で Author が少なくとも 1 回、そして 2 回を超えずに出現することを規定しています。minOccursmaxOccurs のデフォルト値は、element に対して 1 です。エレメントchoice は、そのエレメントの子要素が 1 つだけ、インスタンスの中で出現させる宣言です。別のエレメントall は、グループ内のすべての子要素が 1 回または 0 回、任意の順序で出現するという制約を表現する宣言です。リスト 12 は、Book の中でTitleAuthor の両方が順序を問わず出現してもよく、どちらも出現しなくてもよいという制約を表現しています。このような制約を DTD で表現するのは困難です。

リスト 12: エレメントにすべてのタイプを定義する必要性を示す
<xsd:element name='Title' type='string'/>
<xsd:element name='Author' type='string'/>
<xsd:element name='Book'>
  <xsd:complexType>
    <xsd:all>
      <xsd:element ref='Tile'/>
      <xsd:element ref='Author'/>
    </xsd:all>
  </xsd:complexType>
</xsd:element>

基本の先へ

ここまでで、XML スキーマでエレメントを定義するために必要な基礎的な概念を網羅し、簡単な例をとおしてその能力の一端を垣間見ました。さらに多くの強力なメカニズムが利用できます。

  • XML スキーマには、タイプ継承に対する高度なサポートがあり、以前に定義された構造の再利用が可能です。いわゆるファセット を使用することにより、別のタイプの値のサブセットを表す新しいタイプを派生させることができます。たとえば、列挙、範囲指定、またはパターン・マッチングによって、サブセットを定義することができます。この記事の例では、ProductCode タイプはpattern ファセットを使って定義されたものです。サブタイプにより、基本タイプにエレメント宣言や属性宣言をさらに追加することもできます。
  • サブタイプをすべて定義できるのか、また特定の文書中でサブタイプを置換できるのかを、いくつかのメカニズムによって制御することができます。たとえば、InvoiceType (送り状番号のタイプ) にはサブタイプができないことを表現できます。これはつまり、だれも新しいバージョンのInvoiceType を定義できないということです。さらに、特定の文脈において、ProductCode タイプのサブタイプはいずれも置換できないことを表現できます。
  • サブタイプは別として、等価性タイプを定義することができます。これは、あるタイプの値を別のタイプで置き換えることができるというものです。
  • エレメントまたはタイプを抽象型として宣言することにより、XML スキーマはその置換を強制するためのメカニズムを提供します。
  • 便宜上、属性およびエレメントのグループを定義して名前を付けることができます。グループを引き続き参照することで、再利用が可能になります。
  • XML スキーマでは、スキーマに注釈を付けるための 3 つのエレメントを提供しています。それは、appInfodocumentation、そしてannotation です。これらは、スキーマを読む人のため (documentation) と アプリケーションのため (appInfo) に用意されています。
  • 子エレメントの特定の属性に基づく固有性制約を表現することができます。

W3C サイトの資料を通し (参考文献を参照)、また広範な情報を得るため dW の XML ゾーンを調べることにより、XML スキーマについて理解を深めてください。これまでに XML スキーマ仕様は、Candidate Recommendation に至るところまで承認が進んでおり、いっそう多くの人がそれを利用するようになることは間違いありません。

参考文献

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=XML
ArticleID=241038
ArticleTitle=XMLスキーマの使用法の基本: エレメントの定義
publish-date=08012000