OpenLaszloでマルチデバイス対応RIAを作ろう

第8回データの取り扱い その1

OpenLaszloはXML形式のデータを取り扱うことができます。データはプログラムソースの中に埋め込んでも良いし、外部ファイルにしても良いです。GET/POSTを送信してXMLが返ってくるRESTが使えるのでサーバサイド言語を経由してデータベース内のデータも取り扱えます。ネット上のWebサービスAPIでXMLを返してくるものも使えます。

プログラム中に書く場合は固定的なデータを格納しておく用途、外部ファイルはアプリの挙動を簡単に変更するための設定ファイル用途として使い、ユーザの実データはRESTを使ってデータベースに保存する、という使い分けができます。

<dataset>、XPath、レプリケーション

OpenLaszloでXMLデータを扱うためにまず習得する必要があるのは<dataset>、XPath、レプリケーションの3つです。<dataset>はXMLデータを格納するタグ、XPathはXMLデータの特定のデータを指定するための構文、レプリケーションはデータの複製表示機能です。

リスト1のXMLデータをOpenLaszloで取扱ってみましょう。LZX自体もXML形式なのでややこしいですが、一応別物なので混同しないようにご注意ください。

リスト1 XMLデータ
<daimyou address="清須">
  <sei>織田</sei>
  <mei>信長</mei>
</daimyou>

リスト1のXMLデータをOpenLaszloで表示するにはリスト2のように書きます。

リスト2 リスト1のXMLデータを表示
<canvas proxied="false" bgcolor="0xffffcc"> 
  <dataset name="ds">
    <daimyou address="清須"><!--(1)-->
      <sei>織田</sei>
      <mei>信長</mei>
    </daimyou>
  </dataset>
  <text datapath="ds:/daimyou/sei/text()"/><!--(2)-->
  <text datapath="ds:/daimyou/mei/text()"/>
  <text datapath="ds:/daimyou/@address"/><!--(3)-->
  <simplelayout axis="x"/>
</canvas>

リスト2 サンプル

リスト2の(1)について、<dataset>の中にリスト1のXMLデータを記述しています。そのXMLにアクセスするための識別用に<dataset>にdsという名前をつけています。LZXでは<dataset>(の名前)を介してXMLデータにアクセスします。

リスト2の(2)について、文字列表示タグの<text>を使っていますが文字列を記述する代わりにdatapath属性を指定しています。datapathを使うとXPath記法を使って<dataset>内のXMLデータを取得することができます。ds:/daimyou/sei/text()の意味は、⁠dsという名前の<dataset>の中にあるXMLデータ<daimyou>の子の<sei>のデータを取り出す⁠⁠、ということになります。text()を使うと「<タグ>データ<タグ>」の形のときのデータ部分を取り出すことができます。

リスト2の(3)について、datapathのds:/daimyou/@addressというのは<daimyou>のaddress属性の値を取り出すという意味です。@を使うと「<タグ 属性="値">データ<タグ>」の形のときの値部分を取り出すことができます。

次にレプリケーションについて。リスト3とそのサンプルデモを見比べてください。

リスト3
<canvas proxied="false" bgcolor="0xffffcc"> 
  <dataset name="ds">
    <person>
      <daimyou name="織田信長" />
      <daimyou name="豊臣秀吉" />
      <daimyou name="徳川家康" />
      <daimyou name="武田信玄" />
      <daimyou name="上杉謙信" />
    </person>
  </dataset>
  <text datapath="ds:/person/daimyou/@name"/>
  <simplelayout/>
</canvas>

リスト3 サンプル

リスト3のXMLデータは5人分あるのに、表示用のタグ<text>は1個しかありません。それでも5人分表示されています。結局リスト3の動作結果はリスト4のように書いたのと同じ結果になるのです。つまり1つの<text>が内部的に人数分だけ複製(=レプリケーション)されたことになります。このレプリケーション機能により、データの数を気にすることなく効率的にコーディングすることができます。

リスト4
<canvas proxied="false" bgcolor="0xffffcc"> 
  <text>織田信長</text>
  <text>豊臣秀吉</text>
  <text>徳川家康</text>
  <text>武田信玄</text>
  <text>上杉謙信</text>
  <simplelayout/>
</canvas>

リスト4 サンプル

リスト5では1人分のデータを横並びにして、それを人数分だけ縦に並べて住所録表示のようにしてみました。

リスト5
<canvas proxied="false" bgcolor="0xffffcc"> 
  <dataset name="ds">
    <person>
      <daimyou address="清須">
        <sei>織田</sei>
        <mei>信長</mei>
      </daimyou>
      <daimyou address="大阪">
        <sei>豊臣</sei>
        <mei>秀吉</mei>
      </daimyou>
      <daimyou address="岡崎">
        <sei>徳川</sei>
        <mei>家康</mei>
      </daimyou>
    </person>
  </dataset>
  <hbox datapath="ds:/person/daimyou"><!--(1)-->
    <text datapath="sei/text()"/><!--(2)-->
    <text datapath="mei/text()"/>
    <text datapath="@address"/>
  </hbox>
  <simplelayout/>
</canvas>

リスト5 サンプル

リスト5の(1)で、横向き均等配置の<hbox>にdatapath="ds:/person/daimyou"を設定しているのは、ds:/person/daimyou単位で横並びにするという意味です。ds:/person/daimyouのデータは3つあるので、ds:/person/daimyouごとに縦に3つ並ぶという仕組みです。datapathのパスの設定をどこで切るかも重要な点です。

リスト5の(2)は、datapathの中のパスが「sei/text()」と途中から始まってますが、親タグ<hbox>のdatapathを継承するので、いわゆる相対パスとしての書き方になります。

外部XMLファイル、リモートXMLデータの取得

XMLデータを外部ファイルにすることができます。リスト6のように<dataset>のsrc属性でファイル名を指定します。

リスト6 外部XMLデータファイルの使用
<dataset name="ds" src="mydata.xml"/>

バックエンドのプログラムからXMLデータを取得する場合は、リスト7のように<dataset>のsrc属性でプログラムのパスを指定します。Webサービスの場合はURLをフルパスで指定します。type="http"はHTTP経由、request="true"はアプリ起動時に自動取得するという意味です。バックエンドのプログラム言語はPHP、Java、C、Perl、Rubyなど何でもよく、GET/POSTでアクセスしたときにXMLを返しさえすればOKとなります。データベースに直接アクセスする機能はOpenLaszlo自体にはありませんが、バックエンドのプログラム経由で可能となります。そのため各種WebサービスのAPIを使ったマッシュアップや、データーベースと連携して動く業務アプリの構築が可能です。

リスト7
<dataset name="ds" src="getdata.php" request="true" type="http" />
または
<dataset name="ds" src="http://xxx.xxxx.xxx/getdata.php" request="true" type="http" />

XMLデータの構造が同じなら、ソース内でも、外部ファイルでも、リモートでも、<dataset>経由でのデータの扱い方は全くおなじになります。つまり、XMLデータ構造さえわかっていれば、バックエンドが完成していなくてもローカルのダミーデータで先行開発していけるということです。

データコンポーネント

<dataset>を使ったデータアクセスが前提のコンポーネントを紹介します。HTMLでいうと<table>で表現される表のコンポーネントです。

<grid>

XMLデータを表形式で表示するコンポーネントです。<grid>は入れ物のタグで、文字列データは<grid>の中に入れた<gridtext>で表示します。ここでは割愛しますが、文字列の見せ方を細かくカスタマイズしたり、チェックボックス、ボタンなどのコンポーネントを行の中に入れたりするには<gridtext>の代わりに<gridcolumn>を使用します。

リスト8
<canvas proxied="false" bgcolor="0xffffcc">
  <dataset name="ds" >
    <root>
      <data data1="CCC" data2="888" data3="たちつてと"/>
      <data data1="FFF" data2="555" data3="まみむめも"/>
      <data data1="AAA" data2="333" data3="さしすせそ"/>
      <data data1="DDD" data2="444" data3="あいうえお"/>
      <data data1="EEE" data2="222" data3="なにぬねの"/>
      <data data1="BBB" data2="666" data3="はひふへほ"/>
      <data data1="III" data2="777" data3="かきくけこ"/>
      <data data1="HHH" data2="111" data3="やゆよ"/>
      <data data1="GGG" data2="999" data3="らりるれろ"/>
      <data data1="JJJ" data2="000" data3="わをん"/>
    </root>
  </dataset>
  <grid datapath="ds:/root" >
    <gridtext datapath="@data1">英字</gridtext>
    <gridtext datapath="@data2">数字</gridtext>
    <gridtext datapath="@data3">ひらがな</gridtext>
  </grid> 
</canvas>

リスト8 サンプル

リスト8の<grid>はデフォルト状態ですが、タイトルをクリックするとオンラインでソートでき、データ項目をクリックするとこれもオンラインで編集できるようになっています。デフォルトでは8項目まで表示可能でそれ以上の場合はスクロールバーが自動で出てきます。

<grid>の見た目や動作を変える細かい設定はリファレンスを参照してください。何が指定できるかをざっと紹介すると、縦横の罫線の表示、1行おきの色分け、デフォルト表示数の変更などです。

XPathについて

XMLデータにアクセスする構文XPathはW3Cの標準ですが、OpenLaszloではそのすべての機能に対応しているわけではありません。OpenLaszloで使えるXPath構文を次の表で紹介しておきます。リスト9のXMLデータを使って、<text>のdatapathの設定(★の部分)を変えるとどのような結果を得られるかをまとめてあります。

リスト9
<canvas proxied="false" bgcolor="0xffffcc"> 
  <dataset name="ds" >
    <world>
      <country area="ヨーロッパ">
        <name>イタリア</name>
      </country>
      <country area="ヨーロッパ">
        <name>ギリシャ</name>
      </country>
      <country area="アフリカ">
        <name>ケニア</name>
      </country>
      <country>
        <name>日本</name>
      </country>
      <space>
        <name>月</name>
      </space>
    </world>
  </dataset>
  <simplelayout/>
  <text datapath="★" />
</canvas>
表1 XPath構文と表示例
設定意味表示
ds:/world/country/name/text()すべてのcountryイタリア,ギリシャ,ケニア,日本
ds:/world/country[2]/name/text()2番目のcountryギリシャ
ds:/world/country[2-3]/name/text()2~3番目のcountryギリシャ,ケニア
ds:/world/country[-3]/name/text()最初~3番目のcountryイタリア,ギリシャ,ケニア
ds:/world/country[2-]/name/text()2番目~最後のcountryギリシャ,ケニア,日本
ds:/world/country[@area]/name/text()area属性が存在するcountryイタリア,ギリシャ,ケニア
ds:/world/country[@area='ヨーロッパ']/name/text()areaがヨーロッパのcountryイタリア,ギリシャ
ds:/world/*/name/text()world直下のすべてイタリア,ギリシャ,ケニア,日本,月
ds:/world/country/@areaすべてのcountryのarea属性の値ヨーロッパ,ヨーロパ,アフリカ
ds:/world/country[3]/@area3番目のcountryのarea属性の値アフリカ
ds:/world/country[2-3]/@area2~3番目のcountryのarea属性の値ヨーロッパ,アフリカ
ds:/world/country[1]/name()1番目のcountryのタグの名前country
ds:/world/country/last()counrtyの数4,4,4,4
ds:/world/*/last()world直下のすべてのデータの数5,5,5,5,5
ds:/world/country/position()countryの連番1,2,3,4
ds:/world/*/position()world直下のすべてのデータの連番1,2,3,4,5

おすすめ記事

記事・ニュース一覧