わたしの前回の記事では、簡単なアーキタイプと複雑なアーキタイプ (補足記事『アーキタイプとは』を参照) を使用して、XMLスキーマ設計を単純化し効率化する方法を示しました。今回の記事では、XML Schemaアーキタイプの1つの実際的な適用例として、「スタイル・シートの使用によるプレゼンテーション・レイヤーへの一貫性のあるアーキタイプの組み込み」について検討します。
プレゼンテーション・プロセスの簡単さは、簡単さ の定義の仕方によって異なります。XMLを使用してデータを処理する場合は、しばしば特定の情報を一貫性のある方法で表現しなければならなくなります。たとえば、カラー・ディスプレイを使用できる場合は、常に、銀行口座がプラスであれば黒い数字で表し、マイナスであれば赤い数字で表すようにします。特定のエレメント値を受け取ってそれをこのように表すXSLTコードを書くのは、非常に簡単です。必要になるたびにこのスタイル・コードを繰り返さなければならない場合は、(さまざまな情報表示を行うため、また各情報をこれと同じようにスタイリングするため)、コピー・アンド・ペーストでエラーをする危険性は深刻です。簡単な例を見て見ましょう。ある文書がリスト1のようにXMLスキーマによって定義されているとします。
リスト1. アーキタイプを含まないカスタマー宣言スキーマ
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="customer" type="customerType" />
<xs:complexType name="customerType">
<xs:sequence>
<xs:element name="customerID" type="xs:integer" />
<xs:element name="checkingBalance">
<xs:simpleType>
<xs:restriction base="xs:decimal">
<xs:totalDigits value="10" />
<xs:fractionDigits value="10" />
</xs:restriction>
</xs:simpleType>
</xs:element> <xs:element name="savingsBalance">
<xs:simpleType>
<xs:restriction base="xs:decimal">
<xs:totalDigits value="10" />
<xs:fractionDigits value="10" />
</xs:restriction>
</xs:simpleType>
</xs:element> </xs:sequence>
</xs:complexType>
</xs:schema>
|
savingsBalance およびcheckingBalance エレメントを正しくスタイリングするために、リスト2のようなテンプレートをXSLTスタイル・シートに作成することができます。
リスト2. アーキタイプを含まないサンプル・フォーマット設定テンプレート
<xsl:template match="savingsBalance | checkingBalance">
<xsl:element name="{name()}">
<xsl:value-of select="format-number(text(), '###,###,##0.00')" />
</xsl:element>
</xsl:template>
bgcolor="#cccccc">
|
しかし、残高(balance)を表す新しいエレメントを追加した場合は、テンプレートを変更する必要があることが分かります。このことは、異なるソース・ドキュメント・タイプが多い場合や、異なるレンダリング・ターゲット (たとえば、無線携帯端末、その他のXMLフォーマットなど) が多い場合は、問題になることがあります。ユーザーが希望するのは、1つのスタイル・シートを書くだけで、オリジナル文書内のすべての残高・タイプ・フィールドを処理でき、しかも作成した各新規文書タイプを再コードしなくて済むようにすることです。このための秘けつは、単純なアーキタイプをXMLスキーマに定義し、それを利用して作業を楽にすることです。
リスト1 のXML構造へ戻って、残高情報を表す単純なアーキタイプを追加してみましょう。そうすると、リスト3のようなスキーマになります。
リスト3. アーキタイプを含んだカスタマー宣言
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="customer" type="customerType" />
<xs:complexType name="customerType">
<xs:sequence>
<xs:element name="customerID" type="xs:integer" />
<xs:element name="checkingBalance" type="balance" />
<xs:element name="savingsBalance" type="balance" />
</xs:sequence>
</xs:complexType>
<xs:simpleType name="balance"> <xs:restriction base="xs:decimal">
<xs:totalDigits value="10" />
<xs:fractionDigits value="10" />
</xs:restriction>
</xs:simpleType>
</xs:schema>
|
アーキタイプを使用したXMLスキーマ宣言が小さくなり、読みやすくなったといえるでしょう。このようにスキーマを構造化することの利点は他にもありますが、それについては後で説明します。XMLスキーマが単なるXML文書であるという事実を利用し、それを別の形式に変換するスタイル・シートを書くことができます。リスト4は、XMLスキーマを受け取り、それをもとにして別のスタイル・シートを作成するスタイル・シートを示しています。
リスト4. スタイル・シートを作成するスタイル・シート
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:element name="xsl:stylesheet">
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<xsl:template match="xs:element[@type='balance']">
<xsl:element name="xsl:template">
<xsl:attribute name="match"><xsl:value-of select="@name" /></xsl:attribute>
<xsl:element name="xsl:element">
<xsl:attribute name="name"><xsl:value-of select="@name" /></xsl:attribute>
<xsl:element name="xsl:value-of">
<xsl:attribute name="select">format-number(text(),
'###,###,##0.00')</xsl:attribute>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
|
リスト4のスタイル・シートについては、注目すべき点がいくつかあります。まず、XMLスキーマ・ネームスペースを先頭で宣言しています。これは、XMLスキーマ・ネームスペースに宣言されているオリジナル・スキーマ内のエレメントと突き合わせをするつもりであることをXSLTプロセッサーに認識させる必要があるからです。次に、すべてのエレメントのスペース除去をオンにしています。このスタイル・シートは可読にするものではないので、結果をできるだけ圧縮することによりスペースを節約することができます。また、突き合わせがアーキタイプによって起動されている点にも注意してください。つまり、オリジナル・スキーマ文書内の特定のエレメントを参照するわけではありません。そうではなく、タイプbalance のエレメントと突き合わせをします。さらに、1つのアーキタイプについて1回だけ実際のスタイル・コードを組み込めばよいわけです。このスタイル・シートを使ってオリジナル・スキーマ・フラグメントをスタイリングすると、その結果のプレゼンテーション・スタイル・シートは図5のようになります。
リスト5. 実動スタイル・シートの生成 (読みやすくするために空白文字を追加)
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="checkingBalance">
<xsl:element name="checkingBalance">
<xsl:value-of select="format-number(text(), '###,###,##0.00')"/>
</xsl:element>
</xsl:template>
<xsl:template match="savingsBalance">
<xsl:element name="savingsBalance">
<xsl:value-of select="format-number(text(), '###,###,##0.00')"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
|
スキーマが変わるたびにスタイル・シートを動的に生成するようにすれば、コード・サイズが大幅に削減され、かつコピー・アンド・ペースト・エラーの発生が少なくなります。たとえば、文書構造をリスト6のように変更したいとします。
リスト6. 新規のmoneyMarketBalanceエレメントを含んだカスタマー宣言
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="customer" type="customerType" />
<xs:complexType name="customerType">
<xs:sequence>
<xs:element name="customerID" type="xs:integer" />
<xs:element name="checkingBalance" type="balance" />
<xs:element name="savingsBalance" type="balance" />
<xs:element name="moneyMarketBalance" type="balance" />
</xs:sequence>
</xs:complexType>
<xs:simpleType name="balance"> <xs:restriction base="xs:decimal">
<xs:totalDigits value="10" />
<xs:fractionDigits value="10" />
</xs:restriction>
</xs:simpleType>
</xs:schema>
|
システムが各新規バージョンのスキーマごとにプレゼンテーション・スタイル・シートを自動的に再生成するので、ユーザーは、同じスタイル・シート (リスト4) を使ってスキーマを実行するだけで、
moneyMarketBalance が組み込まれた次のスタイル・シート (この場合も、空白文字を追加) が生成されます。
リスト7. 新規スキーマの実動スタイル・シートの生成 (読みやすくするために空白文字を追加)
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="checkingBalance">
<xsl:element name="checkingBalance">
<xsl:value-of select="format-number(text(), '###,###,##0.00')"/>
</xsl:element>
</xsl:template>
<xsl:template match="savingsBalance">
<xsl:element name="savingsBalance">
<xsl:value-of select="format-number(text(), '###,###,##0.00')"/>
</xsl:element>
</xsl:template>
<xsl:template match="moneyMarketBalance">
<xsl:element name="moneyMarketBalance">
<xsl:value-of select="format-number(text(), '###,###,##0.00')"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
|
こうすれば、スタイル・シートを変更することなく、変更結果をソース文書に正しく含めることができます (ただし、アーキタイプを正しく使用した場合に限られます)。このため、新しいソース文書タイプの作成や、アーキタイプのプレゼンテーション・フォーマットの変更が非常に簡単に行え、しかも何百もの原書類を検索したり置き換えたりする必要がありません。
スキーマをスタイリングするストラテジーは、複雑なアーキタイプの処理も拡張します。スタイル・シートを使って、特定のアーキタイプを持つエレメントと一致するテンプレートを定義することにより、コードをさらに単純化することができます。もう1つの例を見てください。リスト8のようなスキーマを持つ文書があると仮定します。
リスト8. 複雑なアーキタイプを持つ文書
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="customer" type="customerType" />
<xs:complexType name="customerType">
<xs:sequence>
<xs:element name="customerID" type="xs:integer" />
<xs:element name="mailingAddress" type="address" />
<xs:element name="shippingAddress" type="address" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="address"> <xs:sequence>
<xs:element name="address1" type="xs:string" />
<xs:element name="address2" type="xs:string" minOccurs="0" />
<xs:element name="city" type="xs:string" />
<xs:element name="state" type="xs:string" />
<xs:element name="zip" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
|
リスト9のように、スタイルシートを生成するスタイルシートにアドレス・アーキタイプを定義することによって、メーリングアドレスとシッピングアドレスの両方を整合性よくレンダリングできます。
リスト9. アドレス・アーキタイプのスタイル・シート生成プログラム
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:template match="/">
<xsl:element name="xsl:stylesheet">
<xsl:element name="xsl:output">
<xsl:attribute name="method">html</xsl:attribute>
</xsl:element>
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<xsl:template match="xs:element[@type='address']">
<xsl:element name="xsl:template">
<xsl:attribute name="match"><xsl:value-of select="@name" /></xsl:attribute>
<xsl:element name="p">
<xsl:element name="xsl:value-of">
<xsl:attribute name="select">address1/text()</xsl:attribute>
</xsl:element>
<xsl:element name="br" />
<xsl:element name="xsl:value-of">
<xsl:attribute name="select">address2/text()</xsl:attribute>
</xsl:element>
<xsl:element name="br" />
<xsl:element name="xsl:value-of">
<xsl:attribute name="select">concat(city/text(), ', ',
state/text(), ' ',
zip/text())</xsl:attribute>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
|
リスト9のスタイル・シート生成プログラムをオリジナル・スキーマに対して実行すると、リスト10のようなスタイル・シートが生成されます。
リスト10. アドレス・アーキタイプの実動スタイル・シートの生成
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<xsl:template match="mailingAddress">
<p>
<xsl:value-of select="address1/text()"/>
<br/>
<xsl:value-of select="address2/text()"/>
<br/>
<xsl:value-of select="concat(city/text(), ', ', state/text(), ' ', zip/text())"/>
</p>
</xsl:template>
<xsl:template match="shippingAddress">
<p>
<xsl:value-of select="address1/text()"/>
<br/>
<xsl:value-of select="address2/text()"/>
<br/>
<xsl:value-of select="concat(city/text(), ', ', state/text(), ' ', zip/text())"/>
</p>
</xsl:template>
</xsl:stylesheet>
|
この技法を使用した複雑なアーキタイプのスタイリングは、ターゲット・メディアが異なる同じソースXML文書タイプをターゲットにする場合に特に有効です。たとえば、アドレス情報を携帯電話のディスプレイに送る場合は、市区町村と都道府県だけを含めます。
今回の記事では、アーキタイプを使用してコーディング作業を能率的にする方法について概説しています。この説明は、表面をかじった程度のものです。多くのプレゼンテーション・ターゲット (HTML、ワイヤレス、他のマシン・コンシューマーなど) や、多くの異なるソース文書タイプ (帯域幅の縮小やセキュリティー上の理由から) をサポートしなければならない大型システムの場合は、アーキタイプを正しく使用することにより、一貫性のある正しいスタイル・シートを非常に簡単に出力することができます。
- XSLT言語について詳しく学びたい場合は、Michael Kay著Professional XML (Wrox Press) を参照してください。
- W3C XSLT仕様:XSLTおよびXPath のソースへ直接進んでください。
- XML Schemaのバックグラウンドについては、記事 「XMLスキーマの使用法の基本: エレメントの定義」および 「XML Schema Part 0: Primer」(W3C) を参照してください。(W3C仕様そのもの、つまり「XML Schema Part 1: Structures」および「XML Schema Part 2: Datatypes」を調べることもできますが、この作業は慣れていない人には骨が折れます。)
- データベースの処理に特に役立つXML Schemaの機能について解説したKevin Williamsの 「Soapboxについての小論」と、XML Schemaアーキタイプを定義し、その基本的な使用法を紹介した 「第1回」を読んで、彼の全体的なXML Schemaストーリーを把握してください。
-
Pythonモジュールを使用してXML文書からSQL照会を構成し、次にこのプロセスを反転して、SQL照会からXML文書を作成する操作について解説したDavid Mertzの記事を参照してください。
-
Rendering XML Documents with IBM WebSphere は、WebSphereを使用してXSLTスタイル・シートを適用する方法を説明しています。
-
Solutions 2001 developer conference が8月13日 ~16日にサンフランシスコで開催されました。
Kevin Wiliams氏は、情報管理システムのためのXML設計を専門とするVeridianの一部門であるEquientの主任XMLアーキテクトです。XMLに関する数冊の共著がWrox Pressから出版されています。彼の連絡先はkevin@realworldxml.comです。Kevin Williams氏のWebサイト、www.realworldxml.com では、XMLについて彼が思うこと、ヒント、秘けつ、大胆な主張について知ることができます。