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

第9回 データの取り扱い[その2]

この記事を読むのに必要な時間:およそ 3.5 分

前回はXMLデータを取得して表示する基本を解説しました。今回は,データの細かい操作をするための方法について解説します。データによって処理をかえたり,データを加工して表示したり,ビュー間でデータパスの受け渡しをしたりといったことができるようになります。

データポインタ

データポインタとは

前回出てきたデータパス(datapath)は,主にビュー(文字列など画面上の部品のことです)にdatapath属性として設定し,そこで指定したXPath条件に合うデータをすべて表示するために使います。

それに対してデータポインタは,XMLデータの階層構造の中から1つの階層のみを指定するために使います。データポインタは表示するためというより,1つ1つデータを取り出しては何か処理するという用途に向いています。

データポインタの基本形

実例で説明します。リスト1を実行すると画面上に「世界」とだけ表示されます。処理内容を一言で言うと,<dataset>の直下にある<world>のname属性の値だけを選んで表示,です。

リスト1

<canvas proxied="false" bgcolor="0xffffcc"> 
  <dataset name="ds" >
    <world name="世界">
      <country area="ヨーロッパ" name="イタリア" />
      <country area="ヨーロッパ" name="ギリシャ" />
      <country area="アフリカ" name="ケニア" />
      <country name="日本" />
      <space name="月" />
    </world>
  </dataset>
  <simplelayout/>
  <text id="txt"/>
  <datapointer xpath="ds:/"><!-- ① -->
    <handler name="ondata">
      this.selectChild(); // ②
      var t = this.xpathQuery('@name'); // ③
      txt.setAttribute('text',t); //④
    </handler>
  </datapointer>
</canvas>

以下,リスト1の処理を説明します。

① <datapointer>でデータポインタを宣言します。そのxpath属性で,どの<dataset>のどの階層位置に最初のポインタを置くかを指定します。ポインタというのは,XMLデータの階層構造の中でどの位置を指すか,という指定行為のことです。リスト1ではxpath="ds:/"なので,dsという名前のデータセットのルートつまり<dataset name="ds">の位置にポインタを置いたことになります。

② thisは自分自身つまりデータポインタを指します。selectChild()というメソッドはデータポインタのメソッドで,XMLデータ構造の子の方向へ(=下の階層へ)ポインタを移動するという意味です。ここでポインタは<dataset name="ds">から1階層下の<world name="世界">に移動します。

③ xpathQuery()は,XPathの条件に合うデータを返すメソッドです。使い方はビューのdatapath属性を使うときと同じ感じなのですが,<datapath>は(条件に合致する)値が複数返ってくるのに対して,xpathQueryは値を1つだけ返すところが異なる点です。ここでは,②の処理によって<world name="世界">にすでにポインタがあり,その位置のままで「@name」を指定しているので,⁠世界」が取り出されて変数tに格納されています。

④ txtのtext属性値,つまり<text id="txt"/>用の文字列データとして,変数tの内容(=「世界」⁠を代入しています。つまり,変数tのなかの「世界」という文字列が<text>によって画面に表示されたという仕組みです。

データポインタの操作では,selectChild(),xpathQuery()は必ずと言っていいほど良く使います。ちなみに親方向の階層(上の階層)に移動するにはselectParent()を使います。

データポインタのループ処理

データポインタはXMLデータ中の1つの階層にのみアクセス可能なので,複数データを処理するにはループ処理をする必要があります。よく使うのはdo-whileです。do-whileでは,whileの条件式がtrueの間,doブロック内の処理を繰り返します。条件判断式がdoブロックの後にあるので,最低1回は処理されます。リスト2は全データの中からareaがヨーロッパとアフリカの国名だけを表示するコードです。実行結果は「イタリア,ギリシャ,ケニア」となります。

リスト2

<canvas proxied="false" bgcolor="0xffffcc"> 
  <dataset name="ds" >
    <world name="世界">
      <country area="ヨーロッパ" name="イタリア" />
      <country area="ヨーロッパ" name="ギリシャ" />
      <country area="アフリカ" name="ケニア" />
      <country name="日本" />
      <space name="月" />
    </world>
  </dataset>
  <simplelayout/>
  <text id="txt" multiline="ture"/>
  <datapointer xpath="ds:/"><!-- ① -->
    <handler name="ondata">
      this.selectChild(2); // ②
      do{
        var area = this.xpathQuery('@area'); // ③
        if(area=="ヨーロッパ" || area=="アフリカ"){   // ④
          var name = this.xpathQuery('@name'); // ⑤
          txt.addText(name + "\n"); //⑥
        }
      }while(this.selectNext());  //⑦
    </handler>
  </datapointer>
</canvas>

① データポインタを宣言し,ds:/にポインタを置いています。

② selectChild(2)は2階層下に移動するという意味です。selectChild(2)の括弧内の数字は移動する階層の数で,省略すると1になります。この例では,<dataset name="ds">から2階層下の1番目のデータ<country area="ヨーロッパ" name="イタリア" />にポインタが移ります。

③ area属性値を変数areaに格納しています。

④ area属性値がヨーロッパあるいはアフリカかどうかを判断しています。

⑤ name属性値を変数nameに格納しています。

⑥ addText()は文字列を追加するメソッドです。nameに改行コード(\n)を追加して,txt(<text>)に文字列として追記しています。<text>にmultiline="true"を設定することで複数行の表示に対応させています。

⑦ selectNext()は,同一階層の次のデータにポインタを移動するメソッドです。この例では1番目の<country area="ヨーロッパ" name="イタリア" />に対する処理が終わったら,次の<country area="ヨーロッパ" name="ギリシャ" />にポインタが変わることになります。selectNext()がfalseを返したとき,つまり同一階層内でポインタを移動するデータがなくなったときにこのループは終了します。

ということで,リスト2は<world>直下の全データ5つを1つずつ処理・加工していくという動作になります。このようにデータポインタを使えば,データに対する細かい処理が可能になります。

著者プロフィール

ason(あそん)

京都の在宅ITエンジニア。サーバやネットワーク系が得意。初めて触った言語はOpenLaszlo。現在WebプログラマとしてHTML,CSS,PHP,CMSに詳しくなってきたところ。デスメタルドラマー。

URL:http://xtter.openlaszlo-ason.com/

コメント

コメントの記入