私はSoapboxの記事 (参考文献を参照) で、話のついでに、データ用のXMLスキーマ設計でアーキタイプを使用すると、プロジェクトに必要なコーディングおよび保守の作業を大幅に減らすことができ、またカット・アンド・ペーストのエラーの可能性も減らせることを述べました。このコラムでは、データ用のXMLスキーマにおけるアーキタイプの使用例をいくつか示し、どのような利点があるのかを説明したいと思います。
アーキタイプは、XMLスキーマ内のさまざまなエレメント間で共用することのできる、共通の定義のことです。初期のバージョンのXMLスキーマ仕様では、アーキタイプは独自に宣言されるようになっていました。しかし、今回リリースされたバージョンでは、
simpleType エレメントとcomplexType エレメントを使用してアーキタイプをインプリメントできるようになっています。次に、それぞれの例を見てみましょう。
単純なアーキタイプは、XMLスキーマで提供される組み込みデータ型を拡張することによって作成されます。許容される型の値は、いわゆるファセット (それぞれの組み込みデータ型で設定可能な各種のパラメーターを表す風変わりな用語) によって制約されます。単純なアーキタイプは、別の2つのデータ型の共用体を定義することによって、あるいは、なんらかのデータ型に対応する値のリストを作成することによっても、作成可能です。私たちの目的にとっては、単純なアーキタイプの制限的な宣言が最も興味を引きます。いくつかの例を見てみましょう。
たとえば、リレーショナル・データベース内に、リスト1のようなローンを記述するテーブルが含まれているものとします。
リスト1. ローン・テーブルの宣言
CREATE TABLE loan (
loanID INT IDENTITY,
duration SMALLINT,
initialBalance DECIMAL(10, 2),
currentBalance DECIMAL(10, 2),
interestRate DECIMAL(5, 2))
|
明らかに、これらの値はすべてXMLスキーマ 内の組み込みデータ型に直接マップされますので、ターゲット・スキーマ内のエレメントは匿名のsimpleType エレメントと宣言すればよさそうです。ただし、代わりにいくつかの単純なアーキタイプを使用するように定義することは有効です。その理由を見てみましょう。
この例でアーキタイプを使用している、最も明らかな理由は、2つの残高フィールドの値が類似の概念 (現行値の概念) を表していて、同じ方法で宣言されているということです。リレーショナル・データベースを設計するときには、おそらく、これらのフィールドが同じ方法で定義されるようにするために、大変な苦労をすることになります。仮説的なサンプル・データベースでは、有効数字が10桁で小数点以下が2桁の10進数として定義された、 Balance というユーザー型が定義されることも考えられます。これらの型はXMLスキーマで同じ厳密さで定義する必要があります。これにより、スキーマが解読しやすくなり (適切な名前が付いたデータ型は、記述対象となるデータの型に関する情報を表します)、スキーマ全体での整合性が確保されます (decimal(9, 2) として定義されたフィールドにdecimal(10, 2) を保管しようとして問題が発生するようなことはなくなります)。また、一度定義されたアーキタイプを、そのデータから作成されたすべてのスキーマで使用するようにすると、読者が作成したすべてのスキーマを扱うことのできるコンシューマーの作成が単純化されます。コンシューマーが、OurCompanyから得られる文書を扱うたびに、すべての通貨値が同じ方法で定義されることが保証されます。
一度アーキタイプを定義して、必要なときにそれを再使用するようにすると、スキーマのサイズを大幅に縮小することができます。たとえば、前に述べたSQL表内の2つの残高フィールドを保持するエレメントを定義しているとします。リスト2のように、匿名の単純な型を使用してデータ・エレメントを定義することができます。
リスト2. 匿名の単純な型の使用
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="loan">
<xs:complexType>
<xs:sequence>
<xs:element name="initialBalance">
<xs:simpleType>
<xs:restriction base="xs:decimal">
<xs:totalDigits value="10" />
<xs:fractionDigits value="2" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="currentBalance">
<xs:simpleType>
<xs:restriction base="xs:decimal">
<xs:totalDigits value="10" />
<xs:fractionDigits value="2" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence> </xs:complexType>
</xs:element>
</xs:schema>
|
リスト2のコードは、これで良いように見えますが、超インフレが発生してローンの限度額を1億ドルから100億ドルに変更する必要が生じたとしたら、どうなるでしょう?残高が宣言されているすべての個所を変更しなければならなくなり、当然、厄介なことになります。しかしこの方法の代わりに、リスト3のように、残高を表す名前付きの単純なアーキタイプを使用することもできます。
リスト3. 単純な型のアーキタイプ
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="loan">
<xs:complexType>
<xs:sequence>
<xs:element name="initialBalance" type="balance" />
<xs:element name="currentBalance" type="balance" />
</xs:sequence> </xs:complexType>
</xs:element>
<xs:simpleType name="balance">
<xs:restriction base="xs:decimal">
<xs:totalDigits value="10" />
<xs:fractionDigits value="2" />
</xs:restriction>
</xs:simpleType>
</xs:schema>
|
リスト3では、名前付きの単純なアーキタイプの利点は明らかです。スキーマ宣言ははるかに短くなり (空白に関する宣言を除いても、30バイト程度は短くなります)、スキーマ定義が管理しやすくなります。さらに、(途方もない規模の大減税またはその他のばかげた理由により) そうした超インフレが発生した場合にも、より大規模なローン金額を扱えるように仕様を変更するには、単純なbalance 型の1つの宣言を変更するだけで済みます。
これと同じ種類の論理を複雑なアーキタイプの再利用にも適用することができます。たとえば、製造業のデータベースに顧客テーブルが含まれているものとします。このテーブルは、(部分的に) リスト4のようになっています。
リスト4. 顧客テーブルの宣言
CREATE TABLE customer (
customerID int IDENTITY,
mailingAddress varchar(50),
mailingAddress2 varchar(50) NULL,
mailingCity varchar(30),
mailingState char(2),
mailingZip char(10),
shippingAddress varchar(50),
shippingAddress2 varchar(50) NULL,
shippingCity varchar(30),
shippingState char(2),
shippingZip char(10))
|
この場合にも、いくつかの代替手段があります。これらのすべてのフィールドを単純な型として宣言することも、複雑なアドレス・アーキタイプを作成して、必要な個所でそれを再利用することもできます。リスト5で、これがどのように行われるのかを調べてみましょう。
リスト5. 複雑な型を使用しないコード・サンプル
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="customer">
<xs:complexType>
<xs:sequence>
<xs:element name="mailingAddress"> <xs:complexType> <xs:sequence>
<xs:element name="address">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="50" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="address2" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="50" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="city">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="30" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="state">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:length value="2" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="zip">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="10" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="shippingAddress"> <xs:complexType>
<xs:sequence>
<xs:element name="address">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="50" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="address2" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="50" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="city">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="30" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="state">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:length value="2" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="zip">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="10" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
|
ふぅーっ。スキーマがやや長くなる傾向があることは、話したでしょうか?リスト5の事例では、明らかな代替手段が存在します (つまり、
address という複雑なアーキタイプの作成です)。それを使用した場合、リスト6に示すように、私たちのスキーマは少し短くなります。
リスト6. 複雑な型を使用するコード・サンプル
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="customer">
<xs:complexType>
<xs:sequence>
<xs:element name="mailingAddress" type="addressType" />
<xs:element name="shippingAddress" type="addressType" /> </xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="addressType">
<xs:sequence>
<xs:element name="address">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="50" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="address2" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="50" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="city">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="30" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="state">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:length value="2" />
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="zip">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="10" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
|
この場合にも、リスト6のバージョンのほうがかなり短く、しかも理解しやすくなっています。この例を、さらにほかのアーキタイプ (たとえば、
address およびaddress2 エレメントで使用されるアドレス行を表す単純なアーキタイプなど) を導入することができるという事実と合わせて考えてください。それにより、アーキタイプを適切に使用するとどれほどスキーマが管理しやすくなるか分かるはずです。
今回は、XMLスキーマの設計におけるアーキタイプの使用を見てきました。アーキタイプを慎重に使用し、それに加えて気の利いた命名規則を使用すると、スキーマが短く、保守しやすくなります。アーキタイプを使用することの利点は、ほかにもあります。情報のスタイルを整合させる裏技があるのです。しかし、そのトピックは別の機会に譲ることにします (まもなくご紹介できると思います)。
- XMLスキーマ構造の定義に関する情報は、W3CのXMLスキーマ仕様の第1部に記載されています。組み込みデータ型およびそれらに関して使用可能な制約ファセットについては、XMLスキーマ仕様の第2部を参照してください。XMLスキーマ仕様の第1部と第2部のさらに簡潔な要約を読みたい場合には、W3CのPrimer on XML Schema を参照してください。
- スキーマに関する、より分かりやすい情報については、Wrox Pressから刊行された私の著作Professional XML Schemas を参照してください (この記事が発表されるころには書店に置かれているはずです)。
-
IBMのXML Schema Quality Checker がどれほど優れたツールであるのかは、いくら強調しても強調しきれません。ぜひダウンロードして使ってみてください。読者の救い主となってくれるでしょう。
- データを扱う場合になぜXMLスキーマがDTDよりも優れているのかについては、Kevin Williamsの解説を参照してください。
- IBMのDB2 Extenderページは、DB2をXMLで使用する方法の概要を示し、XMLによる照会に関する詳しいホワイト・ペーパー (PDF形式で見ることができます) へのリンク、および
DB2 Extenderダウンロードへのリンクを提供しています。
-
Solutions 2001開発者コンファレンスが8月13日から18日までサンフランシスコで開催されました。
- 17の質問からなるあなたの開発習慣の調査を試し、ソフトウェア・アプリケーション開発のためのIBMによるXMLのツール作成とサービスを支援してください。
Kevin Wiliams氏は、情報管理システムのためのXML設計を専門とするVeridianの一部門であるEquientの主任XMLアーキテクトです。XMLに関する数冊の共著がWrox Pressから出版されています。彼の連絡先はkevin@realworldxml.comです。Kevin Williams氏のWebサイト www.realworldxml.com では、XMLについて彼が思うこと、ヒント、秘けつ、大胆な主張について知ることができます。