はじめに
この連載では、XMLとXSLを使った高度なUIデザインに挑戦します。XMLとXSL(XML用のスタイルシート言語)を使用して、高度なユーザーインタフェース(UI)コンポーネントを毎回1つずつ作成していきます。
本稿では、連載の第1回で紹介したフォルダツリーを発展させ、親エンティティから子エンティティへの関係線を追加します。
フォルダツリーの変更内容
概要
関係線を追加することで、親子関係が明確に示され、ツリー構造がわかりやすくなります。ページ上の画像やオブジェクトが多くなるという潜在的な難点はありますが、メディアの読み込みについてはそれほど心配しなくていいでしょう。図1に示すのは、関係線付きのフォルダツリーです。
関係線を追加するための変更箇所はすべて、XSLTスタイルシートおよびクライアント側JavaScriptの内部にあります。既にフォルダツリーをご利用の皆さんは、連載第1回の「tree.js」および「tree.xslt」の両ファイルを更新するだけで済みます。主な変更内容について、次の2つの節で紹介していきます。
XSLTの変更内容
実際の関係線は、XSLスタイルシート内で描かれます。関係線を実現するために、2つの変更を加えました。1つ目の変更は、エンティティアイコン(エンティティの状態に応じて表示されるプラス/マイナス記号)の前に、関係線を表示するためのテーブルセルを追加したことです。図2に、ルートテーブル内に追加したこの新しいテーブルセルを示します。
2つ目の変更は、階層を表現するための「hierarchy」テンプレートを追加したことです。このテンプレートの内容は次のとおりです。
<xsl:template name="hierarchy"> <xsl:for-each select="ancestor::*[name() != contents]"> <xsl:choose> <xsl:when test="following-sibling::node()"> <img src="images/I.png"/> </xsl:when> <xsl:otherwise> <img src="images/blank.png"/> </xsl:otherwise> </xsl:choose> </xsl:for-each> <xsl:choose> <xsl:when test="count(contents/*) > 0"> <xsl:choose> <xsl:when test="following-sibling::node()"> <img src="images/Tplus.png" _open="images/Tminus.png" _closed="images/Tplus.png"> <xsl:attribute name="ID">stateImagef <xsl:value-of select="@id"/></xsl:attribute> </img> </xsl:when> <xsl:otherwise> <img src="images/Lplus.png" _open="images/Lminus.png" _closed="images/Lplus.png"> <xsl:attribute name="ID">stateImagef <xsl:value-of select="@id"/></xsl:attribute> </img> </xsl:otherwise> </xsl:choose> </xsl:when> <xsl:otherwise> <xsl:choose> <xsl:when test="following-sibling::node()"> <img src="images/T.png"/> </xsl:when> <xsl:otherwise> <img src="images/L.png"/> </xsl:otherwise> </xsl:choose> </xsl:otherwise> </xsl:choose> </xsl:template>
このテンプレートは次のような画像を参照しています。これらの画像については、後で詳しく説明します。
このテンプレートは、まず、現在のエンティティのすべての上位エンティティ(ここでは「先祖」と呼びます)に対して順に処理を行います。ここでは、<xsl:for-each>
を呼び出すことで、名前が"contents"でないすべての先祖を選択しています。これはつまり、"entity"要素だけを処理対象とし、その子にあたる"contents"要素は除外するということです。この反復処理の目的は、対象エンティティの先祖が兄弟ノードを持つ場合は縦線(|)を描画し、兄弟ノードを持たない場合は空白を描画することです。
次に、このテンプレートは別の<xsl:when>
を実行して、エンティティのコンテンツ要素内にある子ノードの数を確認します。コンテンツ要素が子ノードを持っている場合は、L Plus型またはT Plus型の画像のいずれかを描画します。「L」と「T」という文字は、関係線の基本的な形を表しています。「L」は、親ノードから子ノードへの関係を表すもので、上から下、左から右という流れで読みます。「T」は、Tの字を反時計回りに90度回転させた形で、親ノードから子ノードへの関係と、親ノードからその後続の兄弟ノードへの関係の両方を表し、やはり上から下、左から右という流れで読みます。
さらに、このスタイルシートの最後にある<xsl:when>
では、後続の兄弟ノードがないかを確認します。まだ兄弟ノードがある場合は、縦線(|)にぴったりつながるようにT型の画像を描画します。エンティティが兄弟ノードを持たない場合は、L型の画像を描画し、直接の親ノードに兄弟がないことを表します。
クライアントの変更内容
クライアントコードで変更を加えたのは、expand
メソッドとcollapse
メソッドのみです。行の変更や削除ではなく、いくつかの行を追加しました。図3はInterDevの画面ですが、この中でブレークポイントの付いているものが追加した行です。
それぞれのメソッドでは、エンティティのプラスまたはマイナス記号画像を表すoImage
という参照変数を作成しています。collapse
を実行した場合は閉じた状態のアイコンが、expand
を実行した場合は開いた状態のアイコンが、それぞれフォルダツリー表示に使われます。