japan.internet.com The Internet & IT Network


RSSニュース検索
カテゴリ
> トップページ
> Webビジネス
> Eコマース
> Webファイナンス
> Webマーケティング
> パブリック
> Webテクノロジー
> 携帯・ワイヤレス
> Linux Today
> Linux Tutorial
> J.I.C.ブログ
キャリア
> 転職ならen
> 派遣ならen
> アルバイトならen
> IT求人情報
ヘッドライン
> 今日のヘッドライン
> 週間ヘッドライン
Special Link
> フォトコミュニティ
> ストックフォト
> クリップアート
> イラスト
> フェリカ
> Web2.0
> 写真
イベント&セミナー
> イベントカレンダー
> 書評「IT の耳」
> 出張・接待検索
> ニュースガジェット 注目
無料ニュースメール
> 新規登録
> 変更・解除
> オプトインメールの登録・変更・解除
インフォメーション
> パートナーサイト
転職ならエン
就職ならen
求人ならen
履歴書ならen
アルバイトならエン
CRM/SFAならオラクル
> グループ会社
株式会社アエリア
(株)サンゼロミニッツ
株式会社エアネット
> お問い合わせ
> 広告掲載について
> リンクについて
> 著作権について
> その他お問い合わせ
> 利用規約
> 個人情報保護方針
> 会社概要地図
デベロッパー 2006年2月14日 10:00
デベロッパー・バックナンバー
XMLとXSLを使った高度なUIデザイン:パート1

著者: Joe Slovinski  オリジナル版を読む プリンター用 記事を転送
2006年2月14日 10:00 付の記事
海外internet.com発の記事
このエントリーを含むはてなブックマーク この記事をクリップ! Buzzurlにブックマーク Yahoo!ブックマークに登録 newsing it!

はじめに

 この連載では、XMLとXSLを使った高度なUIデザインに挑戦します。1回に1つずつ、XMLとXSL(XML用のスタイルシート言語)を使用して高度なユーザーインタフェース(UI)コンポーネントを作成していきます。

 今回は第1回として、XMLとXSLで深さ無制限のフォルダツリーを作成してみましょう。以下で説明するフォルダツリーは、XMLフィードとして与えられるフォーマットにXSLスタイルシートを適用し、その適用結果をクライアントに書き出すことで作成されます。ツリー自体とそこに含まれる諸エンティティの展開と折り畳み・最大化と最小化の要求は、すべてクライアント側で処理されます。本稿で使用するクライアントはInternet Explorer 5.5以降です。

 作成したフォルダツリーのデモをサンプルとして用意しています。ダウンロードして、実行してみてください。このダウンロードサンプルには、フォルダツリーを構成する諸ファイル(「tree.xsl」「tree.xml」「tree.js」「tree.css」「common.js」および画像ファイル)が含まれています。

フォルダツリーに固有のアーキテクチャ

 Webページオブジェクトには、いく通りもの作成方法があるのが普通で、フォルダツリーも同様です。フォルダツリーの開発では、フォルダツリー独特のアーキテクチャ条件に留意してください。たとえば、次のような条件です。

  1. ネスティング(入れ子)
  2. 関係線

ネスティング

図1 ブラウザ内でネスティングなし
図1 ブラウザ内でネスティングなし
図2 ブラウザ内でネスティングあり
図2 ブラウザ内でネスティングあり

 図1と図2では、DOM(ドキュメントオブジェクトモデル)内にある各オブジェクトの相互関係とネスティング状態をわかりやすくするために、フォルダツリーに一時的に境界線を描いています。

関係線

 ツリー内部に関係線を引けば、見映えがよくなるだけでなく、大きなツリーの構造が把握しやすくなります。反面、パフォーマンスが低下するというマイナスもあります。100個の項目を含むツリーでは、エンティティ間の関係を表示するだけで約300個の画像が必要になります。画像のキャッシュ保存やプリロードを行うことで多少はパフォーマンス低下を防ぐことができますが、それでも、画像がDOM内に独立のオブジェクトとして存在することは変わりません。関係線なしのインデントだけでも親子関係を示すには十分ですから、本稿では、関係線のないツリーでいくことにします。

XML構造

 ツリーに何を求めるかは、それこそ千差万別です。私がツリーに望むこととあなたが望むことの間には、きっと大きな違いがあるでしょう。ツリーエンティティは、ツリーごとに特異です。そうした特異なツリーエンティティを記述するのに、XMLは最適なインタフェースを備えています。どのフォーマットを選ぶかで、XSLスタイルシートとクライアント動作が大きく変わります。私が選んだのは、再帰的XSLスタイルシートに適したフォーマットです。これは、本稿で取り上げている深さ無限のフォルダツリーという条件をよく満たしています。

 私が作成したXMLドキュメントには、treeという名前のルート要素が含まれています。これはentity要素だけを含むことができます。これらのentity要素を、他のentity要素内のcontents要素の入れ子とすることで、ツリーの構造が暗黙裏に定義されます。次に示すのは、entity要素に属するすべての要素と属性のリストです。

名前種類内容
id属性個々のエンティティを指し示すのに用いられる一意の文字列または整数です。
description要素個々のエンティティの記述。ユーザーに表示されるテキストです。
onClick要素onClickイベントで実行されるクライアント側関数の名前です。
image要素エンティティが閉じたとき、または選択されなかったときに表示される画像です。
imageOpen要素エンティティが開いたときに表示される画像です。
contents要素エンティティ要素を含みます。あるエンティティに子があるかどうかを調べるのに使われます。

 実際のツリーでは、ツリー内部の各オブジェクトに関する具体的データを、エンティティ要素によって付加していきます。具体的データとは、たとえば、そのエンティティによって表されるデータベースレコードのIDかもしれません。次回以降では、各エンティティ固有のコンテキストを作成し、それをoncontextmenu要素として実装する(エンティティ要素に追加していく)方法を紹介します。

 本稿で使用するXMLは次のとおりです。ここでは、わかりやすいように静的XMLドキュメントとして作成していますが、動的XMLデータベースクエリとして実装することもできます。

<?xml version="1.0"?>
<tree>
  <entity id="e1">
    <description>Customers</description>
    <oncontextmenu></oncontextmenu>
    <image>images/book.gif</image>
    <imageOpen>images/bookOpen.gif</imageOpen>
    <contents>
      <entity id="e2">
        <description>Microsoft</description>
        <image>images/book.gif</image>
        <imageOpen>images/bookOpen.gif</imageOpen>
        <onClick>displayCustomer(12345)</onClick>
        <contents>
          <entity id="e3">
            <description>Orders</description>
            <image>images/book.gif</image>
            <imageOpen>images/bookOpen.gif</imageOpen>
            <onClick></onClick>
            <contents/>
          </entity>
        </contents>
      </entity>
      <entity id="e4">
        <description>IBM</description>
        <image>images/book.gif</image>
        <imageOpen>images/bookOpen.gif</imageOpen>
        <onClick>displayCustomer(12346)</onClick>
        <contents>
          <entity id="e5">
            <description>Orders</description>
            <image>images/book.gif</image>
            <imageOpen>images/bookOpen.gif</imageOpen>
            <onClick></onClick>
            <contents/>
          </entity>
        </contents>
      </entity>
      <entity id="e6">
        <description>Sun Microsystems</description>
        <image>images/book.gif</image>
        <imageOpen>images/bookOpen.gif</imageOpen>
        <onClick>displayCustomer(12347)</onClick>
        <contents>
          <entity id="e7">
            <description>Orders</description>
            <image>images/book.gif</image>
            <imageOpen>images/bookOpen.gif</imageOpen>
            <onClick></onClick>
            <contents>
              <entity id="e8">
                <description>#12345</description>
                <image>images/paper.gif</image>
                <imageOpen>images/paper.gif</imageOpen>
                <onClick></onClick>
                <contents/>
              </entity>
              <entity id="e9">
                <description>#12346</description>
                <image>images/paper.gif</image>
                <imageOpen>images/paper.gif</imageOpen>
                <onClick></onClick>
                <contents/>
              </entity>
            </contents>
          </entity>
        </contents>
      </entity>
      <entity id="e10">
        <description>Oracle</description>
        <image>images/book.gif</image>
        <imageOpen>images/bookOpen.gif</imageOpen>
        <onClick>displayCustomer(12348)</onClick>
        <contents>
          <entity id="e11">
            <description>Orders</description>
            <image>images/book.gif</image>
            <imageOpen>images/bookOpen.gif</imageOpen>
            <onClick></onClick>
            <contents/>
          </entity>
        </contents>
      </entity>
    </contents>
  </entity>
  <entity id="e12">
    <description>Reports</description>
    <oncontextmenu></oncontextmenu>
    <image>images/book.gif</image>
    <imageOpen>images/bookOpen.gif</imageOpen>
    <contents>
      <entity id="e13">
        <description>Income</description>
        <oncontextmenu></oncontextmenu>
        <image>images/paper.gif</image>
        <imageOpen>images/paper.gif</imageOpen>
        <contents>
        </contents>
      </entity>
      <entity id="e14">
        <description>Expenses</description>
        <oncontextmenu></oncontextmenu>
        <image>images/paper.gif</image>
        <imageOpen>images/paper.gif</imageOpen>
        <contents>
        </contents>
      </entity>
    </contents>
  </entity>
</tree>

 このXMLファイルの名前は「tree.xml」です。このファイルはダウンロードサンプルに含まれています。

XSLスタイルシート

 図1と図2は、どちらも、XMLドキュメントにXSLスタイルシートを適用して得られた結果でした。XMLドキュメントに適用される標準のXSLスタイルシートは次のとおりです。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"
                language="JavaScript">

<xsl:template match="tree">
  <xsl:apply-templates select="entity"/>
</xsl:template>

<xsl:template match="entity">
  <div onclick="window.event.cancelBubble = true;clickOnEntity(this);"
       onselectstart="return false" ondragstart="return false">
  <xsl:attribute name="image"><xsl:value-of select="image"/>
  </xsl:attribute>
  <xsl:attribute name="imageOpen"><xsl:value-of select="imageOpen"/>
  </xsl:attribute>
  <xsl:attribute name="open">false</xsl:attribute>
  <xsl:attribute name="id">f<xsl:value-of select="@id"/>
  </xsl:attribute>
  <xsl:attribute name="open">false</xsl:attribute>
  <xsl:attribute name="STYLE">
    padding-left: 20px;
    cursor: hand;
    <xsl:if expr="depth(this) > 2">
      display: none;
    </xsl:if>
  </xsl:attribute>
    <table border="0" cellspacing="0" cellpadding="0">
      <tr>
        <td valign="middle">
          <img border="0" id="image">
            <xsl:attribute name="SRC">
              <xsl:value-of select="image"/>
            </xsl:attribute>
          </img>
        </td>
        <td valign="middle" nowrap="true">
        <xsl:attribute name="STYLE">
          padding-left: 7px;
          font-family: Verdana;
          font-size: 11px;
          font-color: black;
        </xsl:attribute>
        <xsl:value-of select="description"/></td>
      </tr>
    </table>
  <xsl:apply-templates select="contents/entity"/>
  </div>
</xsl:template>

</xsl:stylesheet>

 このXSLスタイルシートを使って作成したフォルダツリーを図3に示します。

図3 XSLによる変形
図3 XSLによる変形

クライアント側操作

 このフォルダツリーをそれらしく動作させるには、クライアント側で次の操作が必要です。

  1. 初期化
  2. 展開
  3. 折り畳み
  4. 完全展開(最大化)
  5. 完全折り畳み(最小化)

 この5つの操作を実行するコードを次に示しておきます。このコードは、ダウンロードサンプルの「tree.js」ファイルに含まれています。

function initialize() {
  var xmlDoc
  var xslDoc

  xmlDoc = new ActiveXObject(’Microsoft.XMLDOM’)
  xmlDoc.async = false;

  xslDoc = new ActiveXObject(’Microsoft.XMLDOM’)
  xslDoc.async = false;

  xmlDoc.load("tree/tree.xml")
  xslDoc.load("tree/tree.xsl")

  folderTree.innerHTML = xmlDoc.documentElement.transformNode(xslDoc)
}

function clickOnEntity(entity) {
  if(entity.open == "false") {
    expand(entity, true)
  }
  else {
    collapse(entity)
  }
  window.event.cancelBubble = true
}

function expand(entity) {
  var oImage

  oImage = entity.childNodes(0).all["image"]
  oImage.src = entity.imageOpen

  for(i=0; i < entity.childNodes.length; i++) {
    if(entity.childNodes(i).tagName == "DIV") {
      entity.childNodes(i).style.display = "block"
    }
  }
  entity.open = "true"
}

function collapse(entity) {
  var oImage
  var i

  oImage = entity.childNodes(0).all["image"]
  oImage.src = entity.image

  // collapse and hide children
  for(i=0; i < entity.childNodes.length; i++) {
      if(entity.childNodes(i).tagName == "DIV") {
        if(entity.id != "folderTree") 
entity.childNodes(i).style.display = "none"
        collapse(entity.childNodes(i))
      }
    }
  entity.open = "false"
}

function expandAll(entity) {
  var oImage
  var i

  expand(entity, false)

  // expand children
  for(i=0; i < entity.childNodes.length; i++) {
    if(entity.childNodes(i).tagName == "DIV") {
      expandAll(entity.childNodes(i))
    }
  }
}

Webベースのフォルダツリーの今後の展開

 Web技術の進歩にともない、Webアプリケーション内部にステート情報を維持できるようになって、しだいに多くの機能がサーバ側からクライアント側に移され、インタフェースは複雑になる一方です。しかし、その結果、サーバの負担が軽くなり、インタフェースの使い勝手とアプリケーションのパフォーマンスが向上するわけですから、喜ぶべきことでもあります。

 いずれ、本稿で作成したツリーをさらに発展させ、ツリー内部にあるオブジェクトの挿入・削除・改名・再表示を動的に行うAPIを作成して、紹介したいと考えています。

終わりに

 本稿の内容が、Webアプリケーションインタフェースの質的向上に役立てば幸いです。質問・コメント・提案があれば、筆者紹介にあるアドレスまで遠慮なくメールをお送りください。

 この原稿に目を通し、表現と内容の両方をチェックしてくれたLee McGrawに感謝します。

 次回は、カスタムコンテキストメニューの作成を取り上げます。

本連載のその他の記事

著者紹介

Joe Slovinski(Joe Slovinski)
1993年以来、Webアプリケーションの開発に継続的に携わる。本稿で紹介したコードについてのお問い合わせはJoe Slovinskiまで。


関連記事
  • DAL、B2B システム全体の一元管理サーバー「ACMS E2X」を発表
  • ミツエーリンクス、Ajax を活用したインターフェイスを実現する「Ajax NAVI」を発表
  • SQLXMLとシリアル化を使用して.NETオブジェクトをSQL Serverに保存する
  • AJAX 開発ツール分野、新興企業も続々参入
  • 日本コンピュウェア、Java アプリ性能解析ツール最新版を発表


  • 関連テーマ
  • ブラウザ
  • XML
  • Sun
  • Oracle
  • Microsoft
  • IBM


  • ★最新トップニュース
    コラム IT を変えつつあるのはどの技術?(Webビジネス 8月29日 13:30)
    IT マネジャーと企業幹部の間で、IT を最も大胆に変えつつある技術トレンドを巡って意見の相違があるのは当然だ。これら両陣営は敵対関係にある場合が多いため、両者が今日の技術トレンドを違った角度から見ているのは予想できる。
    国内 CTC、日本 HP、マイクロソフト、Hyper-V ベースの仮想化ソリューションを今秋提供へ(Webテクノロジー 8月29日 13:30)
    伊藤忠テクノソリューションズ(CTC)、日本ヒューレット・パッカード(日本 HP)、マイクロソフトの3社は、2008年8月27日、日本 HP とマイクロソフトのサーバー製品・仮想化技術などを組み合わせ、ソリューション検証を共同で実施する、と発表した。
    海外 Facebook 誕生のいきさつが映画に(Webマーケティング 8月29日 13:20)
    ハリウッドの著名脚本家 Aaron Sorkin 氏が、Facebook に自分のページを開設した。Sony Pictures から依頼を受け、Facebook 誕生物語の映画脚本を書くためという。
    海外 価格競争の影響が出た第2四半期のサーバー売上(Webビジネス 8月29日 13:10)
    IDC が、2008年第2四半期のサーバー市場調査を発表した。売上を得るためにベンダー各社が大幅に値下げしている状況がうかがえる内容だ。
    国内 レッドハット、コンサルもパッケージした低価格の SOA 導入支援サービスを開始(LinuxToday 8月29日 13:10)
    SOA 導入初期段階に必要なコンサルテーションサービスと、ユーザーの状況に合わせて独自に設計する技術者向けのトレーニングをセットにしたもの。JBoss Enterprise SOA Platform ユーザーを対象にしたもの。
    トピックス
    > オススメのIT系求人情報【毎週月曜日更新】
    footer_301.gif


    リサーチ
    > デイリーリサーチDLサイト
    > OnlineResearchPortal (リサーチデータバンク)
    > モバイルリサーチ with goo
    footer_301.gif
    キーワード
    > iPhone > Youtube
    > Google > モバイルノート
    > 半導体 > ウィルコム
    > テーマ一覧はこちら
    footer_301.gif
    セミナー情報
    > 第2回インターネットコムマーケティングセミナー
    「モバイルマーケティングの世界」〜これだけはやっておきたいモバイルマーケティング施策とは〜
    9月24日(水)13:00〜17:00 ITS 山王健保会館
    ※詳しくはこちら
    footer_301.gif
    デベロッパー
    > DevX
    > CodeGuru
    > developer.com
    footer_301.gif
    j.i.c.ブログ
    ブログ一覧
    ベンチャー専門家の目利きブログ「なぜこの企業は伸びるのか?」 【ベンチャー専門家の目利きブログ「なぜこの企業は伸びるのか?」】
    「選択と集中」選択をして集中しない限りは勝てない/メディカル・コミュニケーションズ株式会社(8月29日)
    データメーション 【データメーション】
    Apple は顧客の忠誠心にあぐらをかいているのか? (8月27日)
    Graphic Design Forum 【Graphic Design Forum】
    次へとつながる輪 (8月27日)
    最新テクノロジーの意外な処方箋 【最新テクノロジーの意外な処方箋】
    あなたが舌なめずりしたくなるようなもの(8月26日)
    エンジニアの独り言 【エンジニアの独り言】
    データをローカルに保存するWebアプリケーション(8月22日)
    デスマーチからの脱却 【デスマーチからの脱却】
    30min. iPhoneアプリリリース(8月18日)
    footer_301.gif
    最新コラム一覧
    IT マネジメント IT マネジメント

    IT を変えつつあるのはどの技術?(8月29日)
    最新ハイテク講座 最新ハイテク講座

    繁栄か滅亡か!巨大なエネルギー「原子力」の未来(8月29日)
    developer.com developer.com

    レガシーWebアプリケーションをWebLogic Portal内のフルページIFrameとして統合する(8月29日)
    百式のネットビジネス研究 百式のネットビジネス研究

    友達にあなた特製のクスリを贈ることができる「Get Your Drug On」(8月29日)
    週刊-サイト別アクセス状況データ 週刊-サイト別アクセス状況データ

    ビデオリサーチインタラクティブ調査(月間インターネットオーディエンスデータ)(8月28日)
    「IT の耳」 「IT の耳」

    【書評】『1回の会議・打ち合わせで必ず結論を出す技術』――無意味な会議を撲滅する(8月28日)
    ハードウェアから見たデータベース ハードウェアから見たデータベース

    巨大テーブル活用術1(8月28日)
    ウチのサイトを SEO ウチのサイトを SEO

    検索エンジンが見ている世界(8月27日)
    エンジニア転職ノウハウ開発室 エンジニア転職ノウハウ開発室

    目指せecoエンジニア!グリーンITで地球を救え(8月26日)
    アイレップの SEM フロンティア アイレップの SEM フロンティア

    円滑に SEO を導入・実施するための組織体制を構築しよう(3)(8月26日)
    footer_301.gif
    専門チャンネル
    > セキュリティチャネル > テレコムチャネル
    > サーチエンジンウォッチ
    footer_301.gif
    海外のインターネットコム アメリカ韓国ドイツトルコ
    関連企業のサイト:ストックフォト イラスト ネットストリート ホテル予約サイト タウン情報 出張 事業継承 シミュレーション トランクルーム 優待映画チケット 田舎暮らしガイド オリジナルデザインTシャツ ニタコエ
    Copyright 2008 Jupitermedia Corporation All Rights Reserved. http://www.internet.com/
    space.gif space.gif