はじめに
この連載では、XMLとXSLを使った高度なUIデザインに挑戦します。1回に1つずつ、XMLとXSL(XML用のスタイルシート言語)を使用して高度なユーザーインターフェイス(UI)コンポーネントを作成していきます。
今回は、第1回に作成したフォルダツリーを発展させ、ツリー内部の項目を挿入・更新・削除・名前変更できるようにしてみましょう。すべての操作はクライアントに対して実行されますから、サーバーの負担は軽くて済みます。本稿で使用するクライアントはInternet Explorer 5.5以降です。
実際に動作するデモを見たい方は、ダウンロードサンプルをご利用ください。このサンプルには、管理用のフォルダツリーと表示用のフォルダツリーの両方が含まれています。
フォルダツリーの更新
前回の記事以後、フォルダツリーに次の変更を加えました。
- 自動ID
- 無制限のメタデータサポート
- 挿入/更新機能
- 改名機能
- 削除機能
自動ID
ツリー内のどのエンティティにも、一意のIDが必要です。前回、フォルダツリーを作成したときには、このIDの割り当てをユーザーに任せていました。今回は、このID割り当てが実行時に自動的に行われるよう改めました。
新版フォルダツリーでは、ツリーレンダリングの直前に、XSL変換によって一意のIDが割り当てられます。
<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dt="urn:schemas-microsoft-com:datatypes"> <xsl:template match="/tree"> <xsl:element name="tree"> <xsl:apply-templates select="entity"/> </xsl:element> </xsl:template> <xsl:template match="entity"> <xsl:element name="entity"> <xsl:attribute name="id"> <xsl:value-of select="generate-id(.)"/> </xsl:attribute> <xsl:for-each select="*"> <xsl:if test="name() = 'contents'"> <xsl:element name="contents"> <xsl:apply-templates select="entity"/> </xsl:element> </xsl:if> <xsl:if test="name() != 'contents'"> <xsl:element name="{name()}"> <xsl:value-of select="."/> </xsl:element> </xsl:if> </xsl:for-each> </xsl:element> </xsl:template> </xsl:stylesheet>
スタイルシートは「tree.xml」ファイルを先頭から末尾までたどりながら、generate-id()
メソッドによってエンティティの1つ1つに一意のIDを割り当てていきます。
これがn層アプリケーションで、各エンティティがデータベースから取り出されるようになっている場合は、このプロセスは不要です。データベース中の行に対応する各エンティティには、既に一意のIDフィールドが存在します。
無制限のメタデータサポート
どのツリー操作でも、それぞれの要件に応じた記述的メタデータを使用することができます。これはつまり、エンティティを記述するために、任意の名前と値を持つ要素を追加できるということです。
たとえば、次に示すのは、前回の記事で使用した顧客情報XMLです。「image」は予約語であるため、「image」というエンティティ名を「imageBase」に変更してあることに注意してください。
<entity id="e2"> <description>Microsoft</description> <imageBase>images/book.gif</imageBase> <imageOpen>images/bookOpen.gif</imageOpen> <onClick>displayCustomer(12345)</onClick> <onContextMenu>context/contextCustomer.xml</onContextMenu> <contents> </contents> </entity>
次に示すのは、本稿で使用する顧客情報XMLのサンプルです。
<entity id="e2"> <description>Microsoft</description> <imageBase>images/book.gif</imageBase> <imageOpen>images/bookOpen.gif</imageOpen> <onClick>displayCustomer(12345)</onClick> <onContextMenu>context/contextCustomer.xml</onContextMenu> <contact>Bill Gates</contact> <address1>1234 Microsoft Dr.</address> <address2>Suite 123</address> <city>Microsoft City</city> <state>MS</state> <zip>12345</zip> <phone>(123)132-1234</phone> <contents> </contents> </entity>
本稿のXMLでは、連絡先(contact
)、住所(address
)、電話番号(phone
)などの顧客固有のメタデータが追加されていることがおわかりでしょう。今回のフォルダツリーはこの新しいメタデータを自動的に読み取り、解釈します。
新しいフォルダツリーアーキテクチャでは、子エンティティが親エンティティからメタデータを継承します。たとえば、「Customers」フォルダを右クリックして「Insert」を選択すると、「Customers」フォルダの持つ全メタデータが子にも引き継がれます。