XSLT 2

XSLTのプログラムに手こずっています。

話を簡単にしますと、団地の不具合箇所の写真があります。
各写真に対応して、[号棟]、[部位]、[工事区分]、[写真URL]および[コメント]タグをもったXMLデータを作成します。

たとえば、ある写真に[2号棟]、部位:[外壁]、[修理]要、[pic101.jpg]、[外壁タイルにひびが入っています]という具合です。
WEBのページでは、例えば次のようなコントロールがあって、ユーザがコンボから号棟、チェックボックスで部位、工事区分を選択し、サブミットすると該当する画像をコメント付きで表示したいのです。

xsltInVals2

やるべき仕事は、「XMLデータファイルから、[2号棟]の写真で(かつ)、外壁か屋上か修理か塗装]に関する写真を表示せよ」というものです。

これを仮にDBのSQLで書くと次のようなものです。

Select * From 画像テーブル Where 号棟 = 2 And (外壁 = True Or 屋上= True Or 修理 = True Or 塗装 = True)

このデータの抽出と画面の作成をXSLTでやりたいのです。
データの抽出でいえば、SQLのWhere区を作成したいのですが、これがうまくいきません。
XLSTをよく知る人は簡単な話なのかもしれませんが、素人の私にはよく分かりません。
XPathで次のように書ければ話は簡単ですが、そうはいきません。

<xsl:template match="/画像[号棟 = '2' And (外壁 = 'True' Or 屋上= 'True' Or 修理 = 'True' Or 塗装 =' True')]">
  <xsl:call-templates name="Display"/>
 </xsl:template>

ここには二つの問題があります。
まず、[号棟 = ‘2’ … ]のようにXPATHに二つ以上の条件を書くことができないこと。
つぎにこのような条件をダイナミックに書くことができないことです(多分)。

SQLは文字列ですので、データベースに送信するまでにダイナミックにSQLを作成することができますが、
XSLTではそのような方法はないと思います。

私が苦心の末たどり着いた方法は次のようなものです。

メインテンプレート
すべての画像データに次の処理をする。
1. 検索条件に号棟が記入されているかどうかしらべる。
1.1 号棟の指定がある。
1.1.1. もし画像の号棟が指定の号棟に符合すれば、[外壁][屋上][修理]等の検索条件の値をパラメータとして[工事テンプレート]をコールする。
1.1.2. 符合しなければ、終わり。
1.2 号棟の指定がなければ、[外壁][屋上][修理]等の検索条件の値をパラメータとして[工事テンプレート]をコールする。

工事テンプレート
1. [外壁]パラメータがtrueなら、次の処理をする。falseなら2.の処理をする。
1.1 画像データで[外壁]タグがtrueなら、[表示テンプレート]をコールして終わり。
1.2. falseなら、[外壁]パラメータをfalseにし、[屋上][修理]パラメータをそのままにして、[工事テンプレート]をコールする。
注。この画像は他の条件に符号するかもしれないので、再度[工事テンプレート]をコールするが、[外壁]パラメータは検査済みにしなければいけない。
2. [屋上]パラメータがtrueなら、次の処理をする。falseなら3.の処理をする。
2.1 画像データで[屋上]タグがtrueなら、[表示テンプレート]をコールして終わり。
2.2. falseなら、[屋上]パラメータをfalseにし、[修理]パラメータをそのままにして、[工事テンプレート]をコールする。
3. 以下は同様の処理をします。

注。このテンプレートの主旨は、ある画像を表示するかどうかは、
最初の検索条件を調べ、条件に符合すればこの画像を表示し他の条件をチェックしない。
当該条件に符合しなければ次の条件をチェックし、条件に符合すればこの画像を表示し他の条件をチェックしない。
すべての条件に符合しなければ、この画像は表示しない。ということです。
XSLTでは、ループから抜けるための[exit for]のような仕組みがないので、リカーシブコール(再帰呼び出し)を使うしかないと思います。

表示テンプレート
表示テンプレートはHTMLのTableタグの該当する列に、画像の号棟名や画像そのものやコメントを転記するものです。

XMLおよびXSLTファイルができれば、条件入力用のHTMLファイルを作成し、上のコントロールを配置、表示すべき列等にID(例えば[targetID])を付けて、JavascriptでXSLT変換をし、その結果をターゲットの[innerHTML]に出力すれば望みの画像を表示することができます。

var HTMLtarget = document.all[targetID];
HTMLtarget.innerHTML = XSLProcessor.output;

ところで、なぜ簡単に処理できるデータベースではなく、XSLTにこだわるのかといえば、JavascriptとXML、XSLTにしておけば、サーバーが不要で、どこでも必要な画像をみることができるからです。

ブログ1年

ブログを始めて、1年経過しました。
最初はso-netで、「どうせ長続きはしないだろう」と思って気楽に始めました。

so-netではブログの人気ランキングが出ます。
これをオフにもできるのですが、やはりこのランキングが気になります。
ランキングが上がれば「よかった」と思い、下がればがっかりします。
ランキングの上下を気にするのは本末転倒のような気がしてきて、結局so-netを引き上げました。

so-netでは、書いている人間がどこの誰かも分からないし、日常的なことも、孫のことも書いていました。
が、今のサイトを使うようになって、仕事のことを原則にして続けてきました。

余談ですが、先日このブログに孫の写真を出していたら、「やめてくれ。誘拐でもされたらどうする」と息子夫婦にいわれて、
「どうしてこの子の居所がわかるのだ」と思いましたが、親がいうので取り下げました。
(後日孫は大きくなったので、小さいときの写真は誰だかわからないだろう。と当時の写真を載せています)

このブログでは、読者からの投稿等コミュニケートの手段を原則ストップしています。
ここに掲載している私のコードも完全とは思っていないし、色々なご意見もいただきたいのですが、
いたずらが嫌なことと、投稿を気にしてそのことに左右されるとまた本末転倒になると思うからです。

つたないブログに毎日100人近くの人がアクセスしてくださっています。
感謝しますと同時に、これまでの形でのブログはいつまでも続かないと思いますので、
皆様にもなんらかの参加ができるようなことも考えたいと思っています。

Perl, PHP, SmartyそしてXAMPP

私がPerlに出会ったのは随分前のことです。
きっかけは何だったか忘れましたが、Perlに出会って以来すっかりPerlのことが気に入っています。
UNIXのShellに比べるととても柔軟で親しみやすいスクリプトなので、チョコチョコっとコードを書いて実行して楽しんでいました。
例えばフォルダにある沢山のファイル名にいっせいに接頭文字入れるとか、ファイルの行数をカウントするとか。
なによりもパターンマッチングが秀逸なので、コードや文字データで何かを探すときや変更するときによく使います。

出会った当時私はどこからかサンプルを見つけてきて簡単なCGIを書いたと思いますが、WEBの世界がこのように日常的ではなかったし、PerlそのものがCGI言語としてこんなに発展するとは思いませんでした。

どちらにしても私はWEBの世界は趣味程度しか知りません。
WindowsがUNIXを凌駕して以来、私は殆どWindows Formアプリケーションの仕事をしてきました。

Windows Formプログラマが、WEBプログラムで最初に理解しなければいけないのはポストバックです。
ユーザがブラウザからURLに要求を出すと、そのURLに対応したページがインターネットを介してブラウザにダウンロードされます。
ユーザがそのページに何かを入力しサブミットすると別のページに移動することもありますが、入力に不正があると通常サーバーはメッセージをつけて再度同じページをブラウザに送ります(ポストバック)。
すなわち一つのページ(プログラム)には、最初にユーザに表示される場合と、サーバーに送られた情報が再度ユーザに送り返される場合の両方の処理を書いておかなければなりません。
ページの大半をPerlでかいた場合、この仕組みをしっかり整理してかからないとプログラムが大変読みにくくなります。

その点PHPはHTMLの文書にPHPスクリプトを直接書き込むので、Perlですべてを書くことに比べれば可読性は格段によくなります。
しかしそれも限界があり、複雑なPHPのページではやはり読みやすいものではありません。

そこで[フレームワーク]の考えがでてきたと思います。
先にも書きましたが、私はWEBは素人で余り知りませんが、たまたまSmartyに出会いました。確かCMSのXOOPSをいたずらしていた時期だと思います。XOOPSにもSmartyが使われているらしいと知り、Smartyを勉強することにしました。

日本語のいい解説書がないので、英文のSmartyを読みました(著者は欧米人ではなくアジア人のようですが、なに人かよく分かりません)。
この本は必ずしもしっかり書いた本ではありませんが、入門書としては親しみの持てる解説書です。

Smartyはビジネスレイヤと表示レイヤを明確に分け、ビジネスレイヤはプログラマが、表示レイヤはデザイナが担当できるようにしたものです。
ビジネスロジックはPHPのプログラムです。
表示レイヤはテンプレートと言われるファイルで(拡張子はtplです)、基本的にはHTML文書ですが、ビジネスレイヤと通信し、ビジネスレイヤから送られてきたデータを展開するための仕組みが組み込まれています。

大変シンプルで好感を持っています。機会ある毎に使いたいと思っています。
ただし、PHPのフレームワークとしてはSymfonyが有名のようです。すこし勉強しようとしたのですが、なにか大掛かりのようで躊躇しています。
これも無料で使えますので機会があれば挑戦したいと思います。

ところで、PerlははじめはCPANのもの、ここ数年はActivePerlを使っていました。通常のバッチプログラムは、いずれもコンソール画面からコマンドを入力する形で実行します。
「いまどき、コマンドをたたく時代ではなかろう」とは思いましたが、ActiveStateのものは高価だし、無料のものは碌なものはないしと思っていましたが、ありました。
Strawberry Perl(開発環境はPadreと名づけられています)が無料であり、CPANが動作するのでとてもいいと思います。
今後はPerlはこのPadreを使いたいと思います。

WEBの開発用サーバとして、私はWindows Professionalに付属しているIISを使っていました。
今私はVistaのHomeをメインに使っていますのでIISが付属していません。
WEBサーバーに困っていましたが、XAMPPという便利はサーバーがあることが分かりました。
WEBの専門家は皆さんご存知なのでしょうが、Apacheにperl、php、mysql等々必要なコンポーネントがすべて組み込まれていて、しかもインストールもきわめて簡単です。
今後はWEB開発はIISが必然でない限り、XAMPP一本でいこうと思っています(ところが現在までのところ、XAMPPはXPでは問題ないのですが、私のVista Homeで動作しません。ポートの関係かと思います)。

XSLT

VB6プロジェクトのバージョンアップは目処がついてきました。
ただし、今回ACCESSを使っているのでLINQを十分に活用できなくて、大部分はADO.NETを使用することになりそうです。

この作業そのものが、本来の仕事から外れているのですが、さらにWEBの作業が入ってきました。
ある団地が古くなってきたので、故障箇所を写真にとって、条件に応じて画像を表示するというものです。
現在は200程度の画像ですが、将来はもっと増えると思います。

10年近く前にXSLTの勉強をしました。XSLTは何故か気に入っています。手続き型のプログラムではなく、宣言型のプログラムですが、プログラミングがパズルを解くような感じでうまくいくと快感です(パズルみたいなせいか、忘れるのも早いように思います)。

画像にコメントや複数のフラグ(例えば[外壁]とか[屋上]とか)をつけて、それらのフラグに応じて該当する画像を表示します。
ACCESSのフォームをつくり、各画像に対するコメントやフラグを付けていって、そのデータテーブルをXMLファイルとして出力します。
列名に漢字を使うとXML文書が文字化けするようです。
ブラウザで検索条件を入れる仕組みを作り、サブミットでこのXMLファイルをXSLT変換をして所定の場所に出力します。

XMLに対するXSL変換はほとんどの(多分すべての)WEB言語がサポートしています(PHPでもPerlでもOK)。
今回はWEBサーバーに依存しないJavascriptを使います。変換のプログラムは大したことではなく、XSLTをどう作るかが中心的な仕事です。
先にも書きましたが、XSLTを雰囲気は覚えていますが、細かいことはすっかり忘れています。
これもばたばたとやっつけたいと思います。

リファクタリング

Windows95以前のプログラミング環境(汎用コンピュータもUNIXもMS-DOSも)、CやFortranのプログラムでは、変数名の長さは8文字以内の英数字に制限されていました(後でしらべたらCの変数名の長さ制限は31文字でした。昔のことはどんどん忘れます)。
ルーティンが大きくなったり、グローバル変数が多くなると、変数名の命名規則をしっかりしていないと、変数名が足りなくなります。
そのためどうしても意味の無い規則的な変数名になります。

Visual Studioの開発環境になって変数名の長さに制限がなくなり日本語も使えるようになりましたので、変数名の命名が容易になりましたが、その分変数や関数の命名がぞんざいになりがちです。

まだ冬の並木です
まだ冬の並木です

コーディングについては、Steve McConnellの[コードコンプリート]は示唆に富んだとてもいい教科書です。
だけど、それはそれとして、それも鵜呑みにしないで自分流の命名をしたい([コードコンプリート]は英語でのプログラムを想定しているので、大文字と小文字の使い分けを利用しているが、日本語ではそうはいかないから、[コードコンプリート]を100%踏襲できない理由でもある)。
さりとてもちろん無機的で規則的な名前にしたくない、という気持ちがあります。
しかし結果として未だにいい命名ができなくて、はっきり言って統一性のないコードで、ブログでひと様にお見せできるようなコードではないのですが、恥を忍んで仕組みとしてのコードをこのブログでご紹介しています。

さて、そんな中でとても重宝しているのがVBプロパーのリファクタリングの機能-変数名、関数名等の変更用の[名前の変更]です。
またVBでは[DevExpress]の[Refactor!]が使えます。
[Refactor!]では、メソッドの引数並びの変更や変数宣言の位置の変更ができます。
メソッド名、コントロール名、変数名等をどこか一箇所で変更すると、プロジェクト全体にわたって変更してくれます。
同じく引数並びを変更すると、プロジェクト全体で変更してくれます。
これだけでもコードを見やすくするにはとてもありがたいツールです。