2020年1月31日金曜日

Kaleidox: Matrix

BigDataやAIなどがアプリケーションを構成する重要部品となってきています。このBigDataやAIをアプリケーションで扱う上で重要な技術要素として行列(matrix)があります。

Kaleidoxでは行列をMatrixオブジェクトとして記述して各種行列演算をすることができます。

入力

Matrixオブジェクトの入力方法として以下の方法について見ていきます。

  • Matrixリテラル
  • matrix-load関数
Matrixリテラル

Matrixオブジェクトのリテラルは以下のように二重のカギ括弧で囲まれたエリアに改行と空白を区切り記号として記述したものです。

[[
43.055248 141.345505 8.0 1158
38.254162 140.891403 11.9 1219
35.680909 139.767372 15.3 1460
35.154919 136.920593 14.9 1575
34.702509 135.496505 16.2 1400
34.377560 132.444794 15.0 1603
33.579788 130.402405 16.0 1690
26.204830 127.692398 22.4 2128
]]

REPLから入力すると以下のようになります。

kaleidox> [[
43.055248 141.345505 8.0 1158
38.254162 140.891403 11.9 1219
35.680909 139.767372 15.3 1460
35.154919 136.920593 14.9 1575
34.702509 135.496505 16.2 1400
34.377560 132.444794 15.0 1603
33.579788 130.402405 16.0 1690
26.204830 127.692398 22.4 2128
]]
Matrix[4x8]
kaleidox> :show
Matrix[4x8]
┌                                ┐
│43.055248 141.345505 8.0  1158.0│
│38.254162 140.891403 11.9 1219.0│
│35.680909 139.767372 15.3 1460.0│
│35.154919 136.920593 14.9 1575.0│
│34.702509 135.496505 16.2 1400.0│
│34.37756  132.444794 15.0 1603.0│
│33.579788 130.402405 16.0 1690.0│
│26.20483  127.692398 22.4 2128.0│
└                                ┘
matrix-load関数

matrix-load関数でCSVファイルの内容からMatrixオブジェクトを生成します。matrix-load関数では内容の中から自動的に行列化可能な数値部分を取り出してMatrixオブジェクトにします。

日本の都市について緯度経度と平均気温、降水量を記述したCSVファイル city.csv を用意します。

都市,緯度,経度,平均気温,降水量
札幌,43.055248,141.345505,8.0,1158
仙台,38.254162,140.891403,11.9,1219
東京,35.680909,139.767372,15.3,1460
名古屋,35.154919,136.920593,14.9,1575
大阪,34.702509,135.496505,16.2,1400
広島,34.377560,132.444794,15.0,1603
福岡,33.579788,130.402405,16.0,1690
那覇,26.204830,127.692398,22.4,2128

matrix-load関数を使うと以下のようにMatrixオブジェクトを取得することができます。

kaleidox> matrix-load file:city.csv
Matrix[4x8]
kaleidox> :show
Matrix[4x8]
┌                                ┐
│43.055248 141.345505 8.0  1158.0│
│38.254162 140.891403 11.9 1219.0│
│35.680909 139.767372 15.3 1460.0│
│35.154919 136.920593 14.9 1575.0│
│34.702509 135.496505 16.2 1400.0│
│34.37756  132.444794 15.0 1603.0│
│33.579788 130.402405 16.0 1690.0│
│26.20483  127.692398 22.4 2128.0│
└                                ┘
Tableオブジェクト

TableオブジェクトからMatrixオブジェクトを取得することができます。

引き続きCSVファイル city.csv を使用します。

都市,緯度,経度,平均気温,降水量
札幌,43.055248,141.345505,8.0,1158
仙台,38.254162,140.891403,11.9,1219
東京,35.680909,139.767372,15.3,1460
名古屋,35.154919,136.920593,14.9,1575
大阪,34.702509,135.496505,16.2,1400
広島,34.377560,132.444794,15.0,1603
福岡,33.579788,130.402405,16.0,1690
那覇,26.204830,127.692398,22.4,2128

このCSVファイルをtable-load関数を使ってTableオブジェクトとして読み込みます。

kaleidox> table-load file:city.csv
Table[5x8]
kaleidox> :show:print
┏━━━━━━┯━━━━━━━━━┯━━━━━━━━━━┯━━━━━━━━┯━━━━━━┓
┃都市  │緯度     │経度      │平均気温│降水量┃
┣━━━━━━┿━━━━━━━━━┿━━━━━━━━━━┿━━━━━━━━┿━━━━━━┫
┃札幌  │43.055248│141.345505│8.0     │1158  ┃
┃仙台  │38.254162│140.891403│11.9    │1219  ┃
┃東京  │35.680909│139.767372│15.3    │1460  ┃
┃名古屋│35.154919│136.920593│14.9    │1575  ┃
┃大阪  │34.702509│135.496505│16.2    │1400  ┃
┃広島  │34.377560│132.444794│15.0    │1603  ┃
┃福岡  │33.579788│130.402405│16.0    │1690  ┃
┃那覇  │26.204830│127.692398│22.4    │2128  ┃
┗━━━━━━┷━━━━━━━━━┷━━━━━━━━━━┷━━━━━━━━┷━━━━━━┛

Tableオブジェクトを起点にさまざまな操作を行うことができますが、ここではmatrixメソッドを使用してMatrixオブジェクトに変換しています。matrix-load関数と同様に行列化可能なデータを抽出してMatrixオブジェクト化しています。

kaleidox> .matrix
Matrix[0x8]
kaleidox> :show
Matrix[4x8]
┌                                ┐
│43.055248 141.345505 8.0  1158.0│
│38.254162 140.891403 11.9 1219.0│
│35.680909 139.767372 15.3 1460.0│
│35.154919 136.920593 14.9 1575.0│
│34.702509 135.496505 16.2 1400.0│
│34.37756  132.444794 15.0 1603.0│
│33.579788 130.402405 16.0 1690.0│
│26.20483  127.692398 22.4 2128.0│
└                                ┘

参照

Matrixオブジェクトを参照して各種データを取得することができます。

準備としてcity.csvに入っているデータをMatrix化したものを変数xに束縛します。

kaleidox> setq x (matrix-load file:city.csv)
Matrix[4x8]
kaleidox> x
Matrix[4x8]
kaleidox> :show
Matrix[4x8]
┌                                ┐
│43.055248 141.345505 8.0  1158.0│
│38.254162 140.891403 11.9 1219.0│
│35.680909 139.767372 15.3 1460.0│
│35.154919 136.920593 14.9 1575.0│
│34.702509 135.496505 16.2 1400.0│
│34.37756  132.444794 15.0 1603.0│
│33.579788 130.402405 16.0 1690.0│
│26.20483  127.692398 22.4 2128.0│
└                                ┘
行の参照

Matrixオブジェクトの行はrowメソッドで取得することができます。引数に行番号を指定します。行番号は0始まりです。

kaleidox> x.row(0)
[43.055248 141.345505 8.0 1158.0]
列の参照

Matrixオブジェクトの列はcolumnメソッドで取得することができます。引数に列番号を指定します。列番号は0始まりです。

kaleidox> x.column(3)
[1158.0 1219.0 1460.0 1575.0 1400.0 1603.0 1690.0 2128.0]
データの参照

Matrixオブジェクトのデータはatメソッドで取得することができます。引数に列番号、行番号を指定します。

kaleidox> x.at(2,3)
14.9

演算

準備として2✕2の正方行列を変数xに束縛します。

kaleidox> setq x [[
1 2
3 4
]]
Matrix[2x2]
kaleidox> :show
Matrix[2x2]
┌       ┐
│1.0 2.0│
│3.0 4.0│
└       ┘
加算

加算は+メソッドです。

kaleidox>+ x x
Matrix[2x2]
kaleidox> :show
Matrix[2x2]
┌       ┐
│2.0 4.0│
│6.0 8.0│
└       ┘
積算

積算は*メソッドです。

kaleidox> * x x
Matrix[2x2]
kaleidox> :show
Matrix[2x2]
┌         ┐
│7.0  10.0│
│15.0 22.0│
└         ┘
逆行列

逆行列はinvメソッドで行います。

kaleidox> x.inv
Matrix[2x2]
kaleidox> :show
Matrix[2x2]
┌                                       ┐
│-1.9999999999999996 0.9999999999999998 │
│1.4999999999999998  -0.4999999999999999│
└                                       ┘
ランク

行列のランクはrankメソッドで取得します。

kaleidox> x.rank
2

出力

Matrixオブジェクトの出力方法として以下の方法について見ていきます。

  • matrix-save関数
  • Table

準備としてcity.csvに入っているデータをMatrix化したものを変数xに束縛します。

kaleidox> setq x (matrix-load file:city.csv)
Matrix[4x8]
kaleidox> x
Matrix[4x8]
kaleidox> :show
Matrix[4x8]
┌                                ┐
│43.055248 141.345505 8.0  1158.0│
│38.254162 140.891403 11.9 1219.0│
│35.680909 139.767372 15.3 1460.0│
│35.154919 136.920593 14.9 1575.0│
│34.702509 135.496505 16.2 1400.0│
│34.37756  132.444794 15.0 1603.0│
│33.579788 130.402405 16.0 1690.0│
│26.20483  127.692398 22.4 2128.0│
└                                ┘
matrix-save関数

Matrixオブジェクトはmatrix-save関数を使ってCSV形式でファイルに保存することができます。

第1引数に保存するファイル名、第2引数にMatrixオブジェクトを指定します。

kaleidox> matrix-save file:output.csv x
t

matrix-save関数で保存したCSVファイルoutput.csvには以下のCSVが格納されます。

"43.055248","141.345505","8.0","1158.0"
"38.254162","140.891403","11.9","1219.0"
"35.680909","139.767372","15.3","1460.0"
"35.154919","136.920593","14.9","1575.0"
"34.702509","135.496505","16.2","1400.0"
"34.37756","132.444794","15.0","1603.0"
"33.579788","130.402405","16.0","1690.0"
"26.20483","127.692398","22.4","2128.0"
Table

Matrixオブジェクトのtableメソッドで行列データをTableオブジェクトに変換することできます。表のカラム名は1からの連番となります。

kaleidox> x.table
Table[4x8]
kaleidox> :show:print
┏━━━━━━━━━┯━━━━━━━━━━┯━━━━┯━━━━━━┓
┃1        │2         │3   │4     ┃
┣━━━━━━━━━┿━━━━━━━━━━┿━━━━┿━━━━━━┫
┃43.055248│141.345505│8.0 │1158.0┃
┃38.254162│140.891403│11.9│1219.0┃
┃35.680909│139.767372│15.3│1460.0┃
┃35.154919│136.920593│14.9│1575.0┃
┃34.702509│135.496505│16.2│1400.0┃
┃34.37756 │132.444794│15.0│1603.0┃
┃33.579788│130.402405│16.0│1690.0┃
┃26.20483 │127.692398│22.4│2128.0┃
┗━━━━━━━━━┷━━━━━━━━━━┷━━━━┷━━━━━━┛

Tableオブジェクトを起点にMatrixオブジェクトによる行列演算の結果を各種応用に利用していくことができます。

まとめ

今回はKaleidoxで行列を扱うMatrixオブジェクトについて説明しました。

Matrixの演算に加えて、CSVによる外部入出力、Tableオブジェクトとの連携を容易に行うことができます。モデル駆動開発の場合でも、BigDataやAIの応用を考えた場合、アクション言語ではドメインモデルと行列を併用してシームレスに連携できる必要があるはずです。Matrixオブジェクトはこのような応用で便利に使用できると思います。

諸元

  • Kaleidox : 0.1.9
気象データ

以下のページ「5.おもな都市の月平均気温・月降水量」のデータを使用しました。

http://www.biodic.go.jp/reports/2-2/hyo/aa126_001.html

2019年12月30日月曜日

Kaleidox: Table

前回はKaleidoxの中軸となるRecordオブジェクトについて説明しました。

今回はRecordオブジェクトと同様にKaleidoxの中軸オブジェクトであるTableオブジェクトについて説明します。

Tableオブジェクトは文字通り表を記述するオブジェクトで、Recordオブジェクトの列にスキーマとヘッダ、フッタの情報を加えたものになっています。

準備

Tableをデータベース入出力で使用するための環境としてKaleidoxの初期化ファイルinit.kldに以下の設定をします。

この設定をしておくと、H2データベースのメモリデータベース上にpersonテーブルが作成され、2レコードが格納された状態になります。

* env

db.default.driver="org.h2.Driver"
db.default.url="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false"

* voucher

** person

#+caption: 特性一覧
|特性  | 名前 | 型     | 多重度 | ラベル  |
|------+------+--------+--------+---------|
| 属性 | id   | int    |      1 | User ID |
| 属性 | name | string |      1 | 名前    |
| 属性 | city | string |      ? | 市      |

* data

** person

*** x

100,Taro,Yokohama
200,Hanako,Kawasaki

* main

store-create 'person
store-insert 'person x
DATA区画

準備として用意したinit.kldでは以下のデータ区画を定義しています。

* data

** person

*** x

100,Taro,Yokohama
200,Hanako,Kawasaki

変数xにCSVで記述された表データを持つTableオブジェクトが束縛されます。

入力

Tableオブジェクトの入力方法として以下の方法について見ていきます。

  • データベース読込み
  • CSVファイル
  • LTSVファイル
  • XMLファイル
  • JSONファイル
  • HTMLファイル
データベース読込み

Kaleidoxでは、データベースアクセスの仕組みとして以下の2つを用意しています。

Store
データストア機能
SQL
SQLで直接データベースアクセス
Store

データストア機能を使うと、スキーマ定義といったメタ情報を登録することで、データベースに対してレコードベースのインタフェースでアクセスすることができます。

データストアからstore-selectで検索すると、検索結果がテーブルを記述するTableオブジェクトに格納されて返されます。

以下ではstore-selectに検索条件を指定せずテーブル名のみを指定しているので全件検索になります。(ただし、読込件数はデフォルト値の件数で制限されます。)

kaleidox> store-select 'person
Table[3x2]

読み込んだTableの詳細情報を表示すると以下になります。

kaleidox> :show
┏━━━┯━━━━━━┯━━━━━━━━┓
┃id │name  │city    ┃
┣━━━┿━━━━━━┿━━━━━━━━┫
┃100│Taro  │Yokohama┃
┃200│Hanako│Kawasaki┃
┗━━━┷━━━━━━┷━━━━━━━━┛

Tableはオブジェクトなのでプロパティまたはメソッドを使って必要な情報を取り出すことができます。

以下headメソッドを使用して先頭の要素を取り出しています。

kaleidox> .head
id:100 name:Taro city:Yokohama
kaleidox> :show
Record[2] name:Taro city:Yokohama
SQL

データストア機能を使わず直接SQLを使用してデータベース内のデータをTableとRecordとして取得することもできます。

sql関数でSQL文を指定するとSQLが発行されます。SELECT文の場合は結果がTableとして返ってきます。

kaleidox> sql "select * from person"
Table[3x1]
kaleidox> :show
Table[3x1]
┏━━━┯━━━━┯━━━━━━━━┓
┃ID │NAME│CITY    ┃
┣━━━┿━━━━┿━━━━━━━━┫
┃100│Taro│Yokohama┃
┗━━━┷━━━━┷━━━━━━━━┛
kaleidox> .head
ID:100 NAME:Taro CITY:Yokohama
CSVファイル

CSVファイルからテーブルを読み込むことができます。

以下のCSVファイルpersons.csvを用意します。

id,name,city
100,Taro,Yokohama
200,Hanako,Kawasaki

CSVファイルの読込みにはtable-load関数を用います。table-load関数の引数にCSVファイルのURLを指定します。ローカルファイルでもHTTP経由でのリモートファイルでも読込み可能です。

kaleidox> table-load file:persons.csv
Tabble[3x2]

showコマンドで内容を表示すると以下のようにTableオブジェクトとして読み込まれています。

kaleidox> :show
Table[3x2]
┏━━━┯━━━━━━┯━━━━━━━━┓
┃id │name  │city    ┃
┣━━━┿━━━━━━┿━━━━━━━━┫
┃100│Taro  │Yokohama┃
┃200│Hanako│Kawasaki┃
┗━━━┷━━━━━━┷━━━━━━━━┛
LTSVファイル

LTSVファイルからテーブルを読み込むことができます。

以下のLTSVファイルpersons.ltsvを用意します。

id:100 name:Taro city:Yokohama
id:200 name:Hanako city:Kawasaki

LTSVファイルの読込みにはtable-load関数を用います。table-load関数の引数にLTSVファイルのURLを指定します。ローカルファイルでもHTTP経由でのリモートファイルでも読込み可能です。

kaleidox> table-load file:persons.ltsv
Table[3x2]
kaleidox> :show
Table[3x2]
┏━━━┯━━━━━━┯━━━━━━━━┓
┃id │name  │city    ┃
┣━━━┿━━━━━━┿━━━━━━━━┫
┃100│Taro  │Yokohama┃
┃200│Hanako│Kawasaki┃
┗━━━┷━━━━━━┷━━━━━━━━┛
XMLファイル

XML文書から以下のいずれかの構造を読み取り、その情報に基づいてTableオブジェクトを生成することができます。

  • 表データ
  • レコードデータ
表データ

XML文書が以下のようにリスト構造になっている場合は表データとして解釈することができます。

<accounts>
  <account>
    <id>100</id>
    <name>Taro</name>
    <city>Yokohama</city>
  </account>
  <account>
    <id>200</id>
    <name>Hanako</name>
    <city>Kawasaki</city>
  </account>
</accounts>

table-make関数はXML文書の構造を解釈してTableオブジェクトとして読み込みます。

このXML文書をpersons.xmlとして用意してtable-make関数を呼び出すとTableオブジェクトとして読み込むことができます。

kaleidox> table-make file:persons.xml
Table[3x2]
kaleidox> :show
Table[3x2]
┏━━━┯━━━━━━┯━━━━━━━━┓
┃id │name  │city    ┃
┣━━━┿━━━━━━┿━━━━━━━━┫
┃100│Taro  │Yokohama┃
┃200│Hanako│Kawasaki┃
┗━━━┷━━━━━━┷━━━━━━━━┛
レコードデータ

XML文書が以下のようにレコード構造になっている場合はレコードデータとして解釈することができます。

<account>
  <id>100</id>
  <name>Taro</name>
  <city>Yokohama</city>
</account>

このXML文書をperson.xmlとして用意してtable-make関数を呼び出すとTableオブジェクトとして読み込むことができます。

レコード構造の場合は1レコードを持つTableオブジェクトとなります。

kaleidox> table-make file:person.xml
Table[3x1]
kaleidox> :show
Table[3x1]
┏━━━┯━━━━┯━━━━━━━━┓
┃id │name│city    ┃
┣━━━┿━━━━┿━━━━━━━━┫
┃100│Taro│Yokohama┃
┗━━━┷━━━━┷━━━━━━━━┛
JSONファイル

JSON文書から以下のいずれかの構造を読み取り、その情報に基づいてTableオブジェクトを生成することができます。

  • 表データ
  • レコードデータ
表データ

JSON文書が以下のように配列になっている場合は表データとして解釈することができます。

[{
  "id": "100",
  "name": "Taro",
  "city": "Yokohama"
},{
  "id": "200",
  "name": "Hanako",
  "city": "Kawasaki"
}]

このJSON文書をpersons.jsonとして用意してtable-make関数を呼び出すとTableオブジェクトとして読み込むことができます。

kaleidox> table-make file:persons.json
Table[3x2]
kaleidox> :show
Table[3x2]
┏━━━┯━━━━━━┯━━━━━━━━┓
┃id │name  │city    ┃
┣━━━┿━━━━━━┿━━━━━━━━┫
┃100│Taro  │Yokohama┃
┃200│Hanako│Kawasaki┃
┗━━━┷━━━━━━┷━━━━━━━━┛
レコードデータ

JSON文書が以下のようにレコード構造になっている場合はレコードデータとして解釈することができます。

{
  "id": "100",
  "name": "Taro",
  "city": "Yokohama"
}

このJSON文書をperson.jsonとして用意してtable-make関数を呼び出すとTableオブジェクトとして読み込むことができます。

レコード構造の場合は1レコードを持つTableオブジェクトとなります。

kaleidox> table-make file:person.json
Table[3x1]
kaleidox> :show
Table[3x1]
┏━━━┯━━━━┯━━━━━━━━┓
┃id │name│city    ┃
┣━━━┿━━━━┿━━━━━━━━┫
┃100│Taro│Yokohama┃
┗━━━┷━━━━┷━━━━━━━━┛
HTMLファイル

HTML文書からTableオブジェクトを生成することができます。この場合は、HTML文章内の表構造を抽出し、条件に適合するものをTableオブジェクトとして取り出します。

以下のHTMLファイルpersons.htmlにはtableタグによって表が1つ定義されています。

<html>
    <head>
<title>表サンプル</title>
    </head>
    <body>
<p>表のサンプルです</p>
<table>
   <thead>
<tr><th>id</th><th>name</th><th>city</th></tr>
   </thead>
   <tbody>
<tr><td>100</td><td>Taro</td><td>Yokohama</td></tr>
<tr><td>200</td><td>Hanako</td><td>Kawasaki</td></tr>
   </tbody>
</table>
    </body>
</html>

このHTMLファイルに対してtable-make関数を適用するとHTML文書内の表データをTableオブジェクトとして抽出することができました。

kaleidox> table-make file:persons.html
Table[3x2]
kaleidox> :show
Table[3x2]
┏━━━┯━━━━━━┯━━━━━━━━┓
┃id │name  │city    ┃
┣━━━┿━━━━━━┿━━━━━━━━┫
┃100│Taro  │Yokohama┃
┃200│Hanako│Kawasaki┃
┗━━━┷━━━━━━┷━━━━━━━━┛

出力

データストア機能を使ってTableのデータをデータベースに格納することができます。

以下ではstore-insert関数を使って、personテーブルにTableの情報を追加しています。

kaleidox> store-insert x
(101)
kaleidox> store-get 'person 101
ID:101 NAME:Hanako CITY:Kawasaki
kaleidox> store-select 'person
Table[3x2]
kaleidox> :show
Table[3x2]
┏━━━┯━━━━━━┯━━━━━━━━┓
┃id │name  │city    ┃
┣━━━┿━━━━━━┿━━━━━━━━┫
┃100│Taro  │Yokohama┃
┃101│Hanako│Kawasaki┃
┗━━━┷━━━━━━┷━━━━━━━━┛

参照

Tableの内容はRecordのシーケンスとして参照することができます。

準備

前述のinit.kldの設定によって、変数xにTableオブジェクトが束縛されています。

kaleidox> x
Table[3x2]
kaleidox> :show
Table[3x2]
┏━━━┯━━━━━━┯━━━━━━━━┓
┃id │name  │city    ┃
┣━━━┿━━━━━━┿━━━━━━━━┫
┃100│Taro  │Yokohama┃
┃200│Hanako│Kawasaki┃
┗━━━┷━━━━━━┷━━━━━━━━┛

このTableオブジェクトを参照の対象にします。

プロパティ取得

Tableオブジェクトのプロパティは以下のようにプロパティ名を指定して取得することができます。

以下ではTableオブジェクトのカラム数をプロパティwidthで、レコード数をプロパティheightで取得しています。

kaleidox> x.width
3
kaleidox> x.height
2
レコード操作

Tableオブジェクトの先頭レコードはプロパティheadで取得することができます。

kaleidox> x.head
id:100 name:Taro city:Yokohama
kaleidox> :show
Record[3] id:100 name:Taro city:Yokohama

また、先頭レコードを除いた残りのレコードを保持したTableオブジェクトはプロパティtailで取得することができます。

kaleidox> x.tail
Table[3x1]
kaleidox> :show
Table[3x1]
┏━━━┯━━━━━━┯━━━━━━━━┓
┃id │name  │city    ┃
┣━━━┿━━━━━━┿━━━━━━━━┫
┃200│Hanako│Kawasaki┃
┗━━━┷━━━━━━┷━━━━━━━━┛

Tableオブジェクトが空の場合はプロパティheadはnilを返します。

kaleidox> setq y x.tail
Table[3x1]
kaleidox> y.tail
Table[3x0]
kaleidox> :show
Table[3x0]
┏━━┯━━━━┯━━━━┓
┃id│name│city┃
┣━━┿━━━━┿━━━━┫
┗━━┷━━━━┷━━━━┛
kaleidox> .head
nil
スキーマ

Tableオブジェクトのスキーマ情報はプロパティschemaで取得することができます。

kaleidox> x.schema
Schema[3] id,int,1 name,string,1 city,string,?
kaleidox> :show
Schema[3]
┏━━━━┯━━━━━━━━┯━━━━━━━━━━━━┓
┃name│datatype│multiplicity┃
┣━━━━┿━━━━━━━━┿━━━━━━━━━━━━┫
┃id  │int     │1           ┃
┃name│string  │1           ┃
┃city│string  │?           ┃
┗━━━━┷━━━━━━━━┷━━━━━━━━━━━━┛

まとめ

今回はKaleidoxの中軸オブジェクトの一つであるTableについて説明しました。

データベースやCSVファイルといった外部リソースの情報をTableオブジェクトとして読込み、Recordオブジェクト単位で処理していくのがKaleidoxの基本処理モデルです。TableとRecordをハブにして各種の連携を進めていきます。

諸元

  • Kaleidox : 0.1.8

2019年11月30日土曜日

Kaleidox: Record

Kaleidoxはレコードを記述するRecordというオブジェクトを提供しています。

RecordはKaleidoxの中軸となるオブジェクトで、データ処理を行う場合などRecordをハブにして様々な連携を行うようになっています。

今回はRecordの使い方について説明します。

準備

Recordをデータベース入出力で使用するための環境としてKaleidoxの初期化ファイルinit.kldに以下の設定をします。

この設定をしておくと、H2データベースのメモリデータベース上にpersonテーブルが作成され、1レコードが格納された状態になります。

* env

db.default.driver="org.h2.Driver"
db.default.url="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"

* voucher

** person

#+caption: 特性一覧
|特性  | 名前 | 型     | 多重度 | ラベル  |
|------+------+--------+--------+---------|
| 属性 | id   | int    |      1 | User ID |
| 属性 | name | string |      1 | 名前    |
| 属性 | city | string |      ? | 市      |

* main

store-create 'person
store-insert 'person id:100,name:Taro,city:Yokohama

入力

LXSVによるリテラル記述とデータベース読込みでRecordを作成することができます。

LXSV

LXSVリテラルによってRecordを作成することができます。

kaleidox> name:Taro,city:Yokohama
name:Taro city:Yokohama

showコマンドで内容を表示すると2つのプロパティを持つRecordであることが分かります。

kaleidox> :show
Record[2] name:Taro city:Yokohama
データベース読込み

Kaleidoxでは、データベースアクセスの仕組みとして以下の2つを用意しています。

Store
データストア機能
SQL
SQLで直接データベースアクセス
Store

データストア機能を使うと、スキーマ定義といったメタ情報を登録することで、データベースに対してレコードベースのインタフェースでアクセスすることができます。

store-get関数ではデータベースのテーブルからデータをRecordとして読み込むことができます。

以下ではpersonテーブルからID 100のRecordを取得しています。

kaleidox> store-get 'person 100
ID:100 NAME:Taro CITY:Yokohama

データストアからstore-selectでRecordを検索すると、検索結果がテーブルを記述するTableオブジェクトに格納されて返されます。

以下ではstore-selectに検索条件を指定せずテーブル名のみを指定しているので全件検索になります。(ただし、読込件数はデフォルト値の件数で制限されます。)

kaleidox> store-select 'person
Table[3x1]

読み込んだTableの詳細情報を表示すると以下になります。

kaleidox> :show
Table[3x1]
┏━━━┯━━━━┯━━━━━━━━┓
┃id │name│city    ┃
┣━━━┿━━━━┿━━━━━━━━┫
┃100│Taro│Yokohama┃
┗━━━┷━━━━┷━━━━━━━━┛

Tableはオブジェクトなのでプロパティまたはメソッドを使って必要な情報を取り出すことができます。

ここではheadメソッドを使用して先頭の要素を取り出しています。この先頭の要素は本記事のテーマであるRecordとして取り出されます。

kaleidox> .head
id:100 name:Taro city:Yokohama
kaleidox> :show
Record[2] name:Taro city:Yokohama
SQL

データストア機能を使わず直接SQLを使用してデータベース内のデータをTableとRecordとして取得することもできます。

sql関数でSQL文を指定するとSQLが発行されます。SELECT文の場合は結果がTableとして返ってきます。

前述したとおり、Tableオブジェクトのheadメソッドを呼び出すと先頭の行がRecordとして返ってきます。

kaleidox> sql "select * from person"
Table[3x1]
kaleidox> :show
Table[3x1]
┏━━━┯━━━━┯━━━━━━━━┓
┃ID │NAME│CITY    ┃
┣━━━┿━━━━┿━━━━━━━━┫
┃100│Taro│Yokohama┃
┗━━━┷━━━━┷━━━━━━━━┛
kaleidox> .head
ID:100 NAME:Taro CITY:Yokohama

出力

データストア機能を使ってRecordをデータベースに格納することができます。

以下ではstore-insert関数を使って、personテーブルにRecordを追加しています。

kaleidox> store-insert 'person id:101,name:Hanako,city:Kawasaki
(101)
kaleidox> store-get 'person 101
ID:101 NAME:Hanako CITY:Kawasaki
kaleidox> store-select 'person
Table[3x2]
kaleidox> :show
Table[3x2]
┏━━━┯━━━━━━┯━━━━━━━━┓
┃id │name  │city    ┃
┣━━━┿━━━━━━┿━━━━━━━━┫
┃100│Taro  │Yokohama┃
┃101│Hanako│Kawasaki┃
┗━━━┷━━━━━━┷━━━━━━━━┛

参照

Recordの内容はプロパティとして参照することができます。

以下のように変数にpにRecordを束縛します。

kaleidox> setq p id:100,name:Taro,city:Yokohama
id:100 name:Taro city:Yokohama
プロパティ取得

プロパティ取得は以下のようにオブジェクトのプロパティを参照することで行なえます。

kaleidox> p.name
"Taro"
XPath

XPathを使ってRecordからプロパティ取得することもできます。

kaleidox> /name p
"Taro"

まとめ

今回はKaleidoxの中軸オブジェクトであるRecordについて説明しました。

次回はもう一つの中軸オブジェクトであるTableについて説明する予定です。

諸元

  • Kaleidox : 0.1.7

2019年10月31日木曜日

Kaleidox: LXSV

Kaleidoxはレコードを記述するRecordというデータ型を提供しています。

このRecordをテキストとして入出力するためのテキストフォーマットとしてLXSVを開発しました。LXSVを使うことでkaleidoxプログラム内でRecordをリテラルとして記述できます。

LXSVはLTSV(Labeled Tab-separeted Values)的なフォーマットを拡張したもので以下の特徴があります。

  • Kaleidoxプログラム内でリテラルとして記述可能
  • LTSVの概ね上位互換
  • 区切り記号を選択することができる

LXSVフォーマット

LXSVはUnicodeによるテキストフォーマットで区切り記号によってキーと値の対の列によるレコードと、改行コードで区切られたレコードの列を表現できます。

例えば以下のようなテキストがLXSVです。

name:Taro,city:Yokohama
name:Hanako,city:Kawasaki

このテキストではキーと値の対の区切り記号として「:」、キーと値の対の間の区切り記号として「,」を用いています。

キーと値の対の区切り記号は「:」固定ですが、キーと値の対の間の区切り記号は以下のルールによって決められます。

  • TAB、SPACE、「,」、「;」の中で最初に登場した文字を区切り記号とする。

このため以下のLXSVはすべて同じデータ構造を記述しています。

区切り記号: TAB

name:Taro city:Yokohama
name:Hanako city:Kawasaki

区切り記号: SPACE

name:Taro city:Yokohama
name:Hanako city:Kawasaki

区切り記号: ,

name:Taro,city:Yokohama
name:Hanako,city:Kawasaki

区切り記号: ;

name:Taro;city:Yokohama
name:Hanako;city:Kawasaki

区切り記号の入力

値の中にTAB, SPACE, 「,」, 「;」といった区切り記号を入れたい場合、以下の3つの方法があります。

  • 区切り記号の使い分け
  • 「"」で囲んで文字列として記述する。
区切り記号の使い分け

区切り記号を可変にしている理由の1つは区切り記号を値に入れたい場合の文字エスケープを回避することを可能にするためです。

name:Taro;city:Yokohama,Kawasaki
name:Hanako;city:Kawasaki,Yokohama

たとえば以下のように値の中に値の列を記述することも可能になります。ここではLXSVの区切り記号に「;」を使っています。そして、値の中の区切り記号に「,」を使っています。

name:Taro;city:Yokohama,Kawasaki
name:Hanako;city:Kawasaki,Yokohama
文字列

値の中にTAB, SPACE, 「,」, 「;」といった区切り記号を入れたい場合には、前述したように別の区切り記号を使うのが有効ですが、別の方法として「"」を使って文字列を指定することもできます。

name:Taro;city:"Yokohama,Kawasaki"
name:Hanako;city:"Kawasaki,Yokohama"

「"」を使って文字列を記述する場合は、「\n」や「\r」といったエスケープ文字を使って文字列に制御文字を入れることができます。また「”」の文字列内に「"」を入れる場合は「\"」として「\」を使ってエスケープします。

name:Taro;city:"Yokohama\nKawasaki"
name:Hanako;city:"Kawasaki\"Yokohama"

LXSVリテラル

Kaleidoxではレコードを記述するRecordというデータ型を提供しています。このRecordをリテラルとして記述する時にLXSVを用います。

kaleidox> name:Taro,city:Yokohama
name:Taro,city:Yokohama
kaleidox> :show
Record[2] name:Taro,city:Yokohama
文字列リテラルでの入力

Recordを文字列に対する修飾を使って入力することができます。文字列に対する修飾は文字列リテラルの前に修飾を示すプレフィックスを指定します。Recordの場合は「record」です。

以下のように使用します。

kaleidox> record"name:Taro,city:Yokohama"
name:Taro,city:Yokohama
kaleidox> :show
Reord[2] name:Taro,city:Yokohama

KaleidoxではLXSVのデータ型も用意されています。このデータ型を使う場合には修飾を示すプレフィックスとして「lxsv」を指定します。

kaleidox> lxsv"name:Taro,city:Yokohama"
name:Taro,city:Yokohama
kaleidox> :show
Lxsv[2] name:Taro,city:Yokohama

まとめ

Recordを使用するための前提となるLXSVについてご紹介しました。

次回はRecordの具体的な使い方について説明する予定です。

諸元

  • Kaleidox : 0.1.6

2019年9月30日月曜日

Kaleidox: JSON

Kaleidoxでは、実用的に利用できるアクション言語としてXML, HTML, JSON, CSV, Excelといったクラウドアプリケーションで使用する各種データ形式を簡単に扱えるようになっています。

前々回、前回とXMLとHTMLの操作方法について紹介しました。

今回はJSONの操作方法について紹介します。

JSONリテラル

例として以下のJSON文書を考えます。

また、このJSON文書を格納したJSONファイルをfile.jsonとして用意します。

{
  "id": "0001",
  "name": "taro",
  "point": 100
}
リテラル記述

KaleidoxではJSON文書をそのままリテラルとして記述することができます。

REPLでも以下のように直接入力することができます。

kaleidox> {
  "id": "0001",
  "name": "taro",
  "point": 100
}
{\n  "id": "0001",\n  "name": "taro",\n  "point": 100\n}
ファイル入力

REPLでJSON文書が格納されているJSONファイルからJSON文書を取り込む時は以下のようにJSONファイルのURLを記述すればOKです。

kaleidox> file:sample.json
{\n  "id": "0001",\n  "name": "taro",\n  "point": 100\n}\n

この例はプロトコルに「file」を指定してローカルファイルを読み込んでいますが、「http」を指定してリモートファイルを読み込むこともできます。

kaleidox> http://example.com/sample.json
{\n  "id": "0001",\n  "name": "taro",\n  "point": 100\n}\n

XPath

KaleidoxではJSON文書に対してXPathでパス検索をかけることができます。

{
  "id": "0001",
  "name": "taro",
  "point": 100
}

まずJSONファイルsample.jsonに対してXPath「@name」で検索すると以下になります。

JSON文書にある属性nameの値を取得することができました。

kaleidox> @name file:sample.json
"taro"

次にXPath「/name」で検索すると以下になります。こちらもJSON文書にある属性nameの値を取得することができました。

JSONにはXMLにある属性と要素の区別がないので、要素に対する検索ですがJSONの属性に対しても有効になっています。

kaleidox> /name file:sample.json
"taro"

XSLT

KaleidoxはJSON文書をXML文書にみたててXSLT変換を行うことができます。

サンプルとして使用しているJSON文書です。

{
  "id": "0001",
  "name": "taro",
  "point": 100
}

このJSON文書に対して提供するXSL記述は以下になります。

<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="html"></xsl:output>

  <xsl:template match="/">
    <HTML>
    <BODY>
    <xsl:apply-templates/>
    </BODY>
    </HTML>
  </xsl:template> 

  <xsl:template match="record">
    <TABLE>
      <THEAD>
        <TR>
          <TH>ID</TH>
          <TH>Name</TH>
   <TH>Point</TH>
        </TR>
      </THEAD>
      <TBODY>
 <TR>
   <TD><xsl:value-of select="id"/></TD>
   <TD><xsl:value-of select="name"/></TD>
   <TD><xsl:value-of select="point"/></TD>
 </TR>
      </TBODY>
    </TABLE>
  </xsl:template> 
</xsl:stylesheet>

XMLやHTMLの場合と同様にXSLファイルに続けてJSONファイルを指定するとXSL変換が行われます。

kaleidox> file:sample.xsl file:sample.json
<HTML><BODY><TABLE><THEAD><TR><TH>ID</TH>
<TH>Name</TH><TH>Point</TH></TR>...

変換後のXML文書を詳細を表示すると以下になります。

無事XSLTでJSONファイルをHTML文書に変換することができました。

kaleidox> :show:print
<HTML><BODY><TABLE><THEAD><TR><TH>ID</TH>
<TH>Name</TH><TH>Point</TH></TR></THEAD>
<TBODY><TR><TD>0001</TD><TD>taro</TD>
<TD>100</TD></TR></TBODY></TABLE>
</BODY></HTML>

Table

XMLやHTMLと同様にJSON文書で記述した表情報をTableデータとして扱うことができます。

サンプルとして使用しているJSON文書です。

{
  "id": "0001",
  "name": "taro",
  "point": 100
}

このJSON文書に対してtable-make関数を適用します。

kaleidox> table-make file:sample.json
Table[3x1]

その結果、幅3、高さ1の表を得ることができました。

この表の内容をshowコマンドで表示すると以下になります。無事HTMLの表の内容を取得できています。

kaleidox> :show
Table[3x1]
┏━━━━┯━━━━┯━━━━━┓
┃id  │name│point┃
┣━━━━┿━━━━┿━━━━━┫
┃0001│taro│100  ┃
┗━━━━┷━━━━┷━━━━━┛

JSON文書がJson Objectの場合は1行のテーブルに変換されます。

レコードシーケンス

JSON文書がJson Objectの配列だった場合は配列の長さ分の行を持ったテーブルに変換されます。

まずJson Objectの配列を持ったJSON文書を用意します。

[{
  "id": "0001",
  "name": "taro",
  "point": 100
},{
  "id": "0002",
  "name": "hanako",
  "point": 200
}]

このJSON文書に対してtable-make関数を適用します。

kaleidox> table-make file:sample-table.json
Table[3x2]

その結果、幅3、高さ2の表を得ることができました。

この表の内容をshowコマンドで表示すると以下になります。無事HTMLの表の内容を取得できています。

kaleidox> :show:print
┏━━━━┯━━━━━━┯━━━━━┓
┃id  │name  │point┃
┣━━━━┿━━━━━━┿━━━━━┫
┃0001│taro  │100  ┃
┠────┼──────┼─────┨
┃0002│hanako│200  ┃
┗━━━━┷━━━━━━┷━━━━━┛

まとめ

今回はJSONの操作について説明しました。

JSONではXPath(パス検索)はXSLT(データ変換)といったXMLで用意されている便利な機能が基本機能として提供されていません。

KaleidoxではJSON文書をXML文書として操作可能にすることで、XMLの便利な機能をJSON文書にも適用できるようにしました。

前々回、前回、今回でXML、HTML、JSONの操作方法についてみてきました。

KaleidoxではXML、HTML、JSONについて詳細を意識することなくシームレスに操作することができることを確認できました。

次回はこのメカニズムの土台となっているRecordについてみていく予定です。

諸元

  • Kaleidox : 0.1.5

2019年8月25日日曜日

Kaleidox: HTML

Kaleidoxでは、実用的に利用できるアクション言語としてXML, HTML, JSON, CSV, Excelといったクラウドアプリケーションで使用する各種データ形式を簡単に扱えるようになっています。

前回はこの中でXMLの操作方法について紹介しました。

今回はHTMLの操作方法について紹介します。

HTMLリテラル

HTMLは元々SGMLベースですが、XMLベースのXHTMLもあります。

XHTMLのみを対象にするとXML処理的には楽ですが、実際のところはSGMLベースのHTMLが主流なのでこちらの方も扱えないといけません。

Kaleidoxでは、SGMLベース、XMLベースのどちらのHTMLもHTMLデータとして扱い、内部的にはDOMで操作しています。

まず以下のHTML文書を考えます。XML的な観点ではすこしブロークンですが、このような形のタグ構造も扱える必要があります。

<b>HTML文書

HTMLリテラルは、文字列リテラルのプレフィックスにHTMLをつけたものになります。

kaleidox> html"""<b>HTML文書"""
<html><head xmlns="http://www.w3.org/1999/xhtml"/><body><b>HTML文書\n</b></b...

showコマンドを使うとHTML全体を表示することができます。

kaleidox> :show
SHtml: <html><head xmlns="http://www.w3.org/1999/xhtml"/><body><b>HTML文書
</b></body></html>

元のHTMLの内容はB要素のみのHTMLの断片ですが、読み込み時にはHTML要素から始まる本格的なHTML文書になっています。これは、HTMLに対するXSLTなどの処理が統一的に行えるように必要な情報を補完しているためです。

ファイル

ファイルに格納されているHTMLは、URIを指定して取り込むことができます。

kaleidox> file:sample.html
<html><head xmlns="http://www.w3.org/1999/xhtml"/><body><b>HTML文書\n</b></b...
kaleidox> :show
SHtml: <html><head xmlns="http://www.w3.org/1999/xhtml"/><body><b>HTML文書
</b></body></html>

XPath

HTMLに対してもXMLと同様にXPathによるアクセスを行うことができます。

まず、HTML文書を読み込みます。

kaleidox> file:sample.html
<html><head xmlns="http://www.w3.org/1999/xhtml"/><body><b>HTML文書\n</b></b...

HTML文書がスタックに積まれたので、これに対してXPath「htmlbody/b」を適用します。

kaleidox> /html/body/b
"HTML文書\n"

XPathを適用の結果、B要素の内容である「HTML文書」を取り出すことができました。

XPathの式の直後にHTMLファイルを指定しても同じ結果を得ることができます。

kaleidox> /html/body/b file:sample.html
"HTML文書\n"

XSLT

HTMLに対してもXMLと同様にXSLTによる変換を行うことができます。

XSLTに使用するXSL文書として以下のものを用意しました。

HTML文書の一部を変更する目的の典型的なXSL文書です。ここではB要素をI要素に変換するXSL文書になっています。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

  <xsl:template match="b">
    <i><xsl:value-of select="."/></i>
  </xsl:template>

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

それではXSL文書をHTMLに適用してみましょう。

XSLT文書のファイル名の後ろにHTML文書名を指定します。すると内部的にはxslt関数が実行され、XSLT変換が行われます。

kaleidox> file:sample.xsl file:sample.html
<html><head xmlns="http://www.w3.org/1999/xhtml"/><body><i>HTML文書\n</i></b...

実行結果のHTML文書をshowコマンドで表示すると以下のようになりました。無事B要素がI要素に変換されています。

kaleidox> :show
SHtml: <html><head xmlns="http://www.w3.org/1999/xhtml"/><body><i>HTML文書
</i></body></html>

スクレイピング

KaleidoxはHTML文書内の表データを抽出する機能を提供しています。

まず表を記述したHTML文書を用意します。

<html>
    <head>
 <title>表サンプル</title>
    </head>
    <body>
 <p>表のサンプルです</p>
 <table>
     <thead>
  <tr><th>A</th><th>B</th></tr>
     </thead>
     <tbody>
  <tr><td>1</td><td>11</td></tr>
  <tr><td>2</td><td>12</td></tr>
  <tr><td>3</td><td>13</td></tr>
     </tbody>
 </table>
    </body>
</html>

このHTML文書に対してtable-make関数を適用します。

kaleidox> table-make file:table.html
Table[2x3]

その結果、幅2、高さ3の表を得ることができました。

この表の内容をshowコマンドで表示すると以下になります。無事HTMLの表の内容を取得できています。

kaleidox> :show:print
┏━┯━━┓
┃A│B ┃
┣━┿━━┫
┃1│11┃
┠─┼──┨
┃2│12┃
┠─┼──┨
┃3│13┃
┗━┷━━┛

まとめ

今回はXMLの操作について説明しました。

次回はJSONの操作方法についてみていく予定です。

諸元

  • Kaleidox : 0.1.4

2019年7月29日月曜日

Kaleidox: XML

アクション言語を実用的に使用するにはXML, HTML, JSON, CSV, Excelといったクラウドアプリケーションで使用する各種データ形式を容易に扱えるようになっている必要があります。これらのデータをプログラム内に取り込んだり、データ形式間の相互運用が簡単にできることが重要です。

Kaleidoxでは各種データ形式の個々の操作性と、これらのデータ形式間の相互運用の両面について最適な記述が可能となるような言語機能を提供しています。

ここではまずXMLの操作についてみていきます。

XMLリテラル

KaleidoxはXMLを第一級の言語要素として考えていることもあり、リテラルで記述することができます。

以下のXMLを考えます。

<account>
  <id>0001</id>
  <name>taro</name>
  <point>100</point>
</account>

まずKaleidoxプログラムですが、以下のように上記XMLを直接XMLリテラルとして記述することができます。

<account>
  <id>0001</id>
  <name>taro</name>
  <point>100</point>
</account>

上記プログラムをsample.kに格納して実行すると以下のようになります。

$ kaleidox sample.k
<account>
  <id>0001</id>
  <name>taro</name>
  <point>100</point>
</account>

XMLリテラルで記述されたXML文書がそのまま評価され、評価結果がXML文書として出力されました。

REPL

REPLで同様の処理を行うと以下のようになります。

kaleidox> <account>
  <id>0001</id>
  <name>taro</name>
  <point>100</point>
</account>
<account>\n  <id>0001</id>\n  <name>taro</name>\n  <point>100</point>\n</acco...

プロンプトからXML文書を入力しています。

通常REPLのプロンプトからは改行を区切りとした一行の式を入力しますが、XMLやJSONなどの構造を持つリテラルはリテラル内に改行が入っていても入力することができます。

kaleidox> :show
<account>
  <id>0001</id>
  <name>taro</name>
  <point>100</point>
</account>

ファイルから読み込む場合はURLを指定します。

kaleidox> file:sample.xml
<account>\n  <id>0001</id>\n  <name>taro</name>\n  <point>100</point>\n</acco...

読み込み結果をshowコマンドで表示すると以下になります。

kaleidox> :show
Xml(String)
<account>
  <id>0001</id>
  <name>taro</name>
  <point>100</point>
</account>

XPath

XML文書を処理する場合にはXPathによるXML文書内のデータアクセスが極めて有効です。

KaleidoxではXPathによるXML文書アクセスを行うことができます。

kaleidox> <account>
  <id>0001</id>
  <name>taro</name>
  <point>100</point>
</account>
<account>\n  <id>0001</id>\n  <name>taro</name>\n  <point>100</point>\n</acco...
kaleidox> /account/name
"taro"

XSLT

XML文書の操作ではXSLTによる変換も重要です。

変換対象のXML文書として前出のものを使用します。ファイルsample.xmlに格納しています。

<account>
  <id>0001</id>
  <name>taro</name>
  <point>100</point>
</account>

XML文書を閲覧用のHTML文書に変換するXSLです。ファイルsample.xslに格納します。

<?xml version="1.0" encoding="Shift_JIS"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="html"></xsl:output>

  <xsl:template match="/">
    <HTML>
    <BODY>
    <xsl:apply-templates/>
    </BODY>
    </HTML>
  </xsl:template> 

  <xsl:template match="account">
    <TABLE>
      <THEAD>
        <TR>
          <TH>Name</TH>
   <TH>Value</TH>
        </TR>
      </THEAD>
      <TBODY>
 <TR>
   <TD><xsl:value-of select="id"/></TD>
   <TD><xsl:value-of select="name"/></TD>
   <TD><xsl:value-of select="point"/></TD>
 </TR>
      </TBODY>
    </TABLE>
  </xsl:template> 
</xsl:stylesheet>

XSLT変換はxslt関数で行うことができます。

引数にはXSLリテラルまたはXSL文書URL、XMLリテラルまたはXML文書URLを指定します。

以下ではXSL文書URLとXML文書URLを指定しています。xslt関数実行の結果、XML文書を変換したHTML文書に得ることができました。

kaleidox> xslt file:sample.xsl file:sample.xml
<HTML><BODY><TABLE><THEAD><TR><TH>Name</TH><TH>Value</TH></TR></THEAD><TB...
kaleidox> :show:print
<HTML><BODY><TABLE><THEAD><TR><TH>Name</TH><TH>Value</TH></TR></THEAD><TBODY><TR><TD>0001</TD><TD>taro</TD><TD>100</TD></TR></TBODY></TABLE></BODY></HTML>

関数を省略してもXSLファイルが先頭の場合はxslt関数が実行されます。

kaleidox> file:sample.xsl file:sample.xml
<HTML><BODY><TABLE><THEAD><TR><TH>Name</TH><TH>Value</TH></TR></THEAD><TB...

Record

Kaleidoxはレコード/テーブル指向の言語なので、各種データをレコードに変換すると、より柔軟にデータ操作を行うことができます。

record-make関数でXMLからレコードを生成する事ができます。record-make関数はスキーマを与えなくてもXML文書の内容からレコードのスキーマを推測します。

kaleidox> record-make file:sample.xml
id:1,name:taro,point:100

Table

XMLをテーブルに変換することで、Kaleidoxが提供するテーブル操作機能を使ってデータ操作を行うことができます。

table-make関数でXMLからテーブルを生成することができます。table-make関数はスキーマを与えなくてもXML文書の内容からレコードのスキーマを推測します。

kaleidox> table-make file:sample.xml
Table[3x1]

生成されたテーブルデータを表示するためにshowコマンドを実行すると以下の情報が表示されます。

kaleidox> :show
Table[3x1]
┏━━━━┯━━━━┯━━━━━┓
┃id  │name│point┃
┣━━━━┿━━━━┿━━━━━┫
┃0001│taro│100  ┃
┗━━━━┷━━━━┷━━━━━┛
リスト

データ列を記述するXML文書として以下のものをsample-list.xmlとして用意します。

<accounts>
  <account>
    <id>0001</id>
    <name>taro</name>
    <point>100</point>
  </account>
  <account>
    <id>0002</id>
    <name>hanako</name>
    <point>200</point>
  </account>
</accounts>

ここからtable-make関数を使ってテーブルを生成します。

kaleidox> table-make file:sample-list.xml
Table[3x2]

生成した結果のテーブルは以下になります。

kaleidox> :show:print
┏━━━━┯━━━━━━┯━━━━━┓
┃id  │name  │point┃
┣━━━━┿━━━━━━┿━━━━━┫
┃0001│taro  │100  ┃
┠────┼──────┼─────┨
┃0002│hanako│200  ┃
┗━━━━┷━━━━━━┷━━━━━┛

まとめ

今回はXMLの操作について説明しました。

次回以降、HTML, JSON, CSV, Excelの順にデータ操作方法についてみていく予定です。

諸元

  • Kaleidox : 0.1.3