2016 02 07

XMLの6

天気が良いので近所を散歩。 そろそろ梅も咲く頃だし。

坂の上

広島に住んでいた頃は、家がちょうどこんな感じの長い坂の途中にあった。

自転車で通学していたので、行きは良いが帰りは結構辛い。 しかしまだ若かった俺は、坂道で自転車を降りて押して上がるのが負けのように思えて、無理矢理漕いで上ってた。 軽いギアで上がれるようになると、わざわざギアを重くしたりして。

当時の俺は、いったい何と戦っていたのか。

甍の波

高幡不動の裏山から見る南平一丁目。 まあ、庶民の町だよな。

落書き

アンパンマン?

腐った木

歩いていて、この辺りに差し掛かったところで 「あれ?」 と何か違和感みたいなものを感じて、その原因を探ろうと辺りを見回して、木が切り倒されているのに気がついた。 前にここを歩いたのが確か先週で、そのときはまだ切られていなかったはず。

腐った木は、虫には良い住処だが、ちょっと強い風が吹けば倒れそうだし、道沿いにあるとやっぱり切らざるを得ないんだろうな。

切られた木

切られた木。 芯がボロボロなのが根元の方。 ちょっとずつ輪切りにしているのは、安全のためだろうか。

梅

高幡不動の梅。 ちょっとやる気になっている。

XML

昨日の続き。 今日は検索処理を実装する。

そもそも何を検索したいのか。

想定しているのはstrutsやspringやiBatisのXMLファイルで、だから検索したいのも 「このactionformを使っているaction」 とか 「このテーブルにアクセスしているSQL定義」 とか、検索条件に該当する文字列はもちろんとして、それを包含する要素が何かも知りたい。

ではどうするか。

今回、XMLの各要素は全てdivを割り当てて表示している。 なので、表示領域の全てのdivを取得して、その中に、というのは innerHTML や innerText のことだが、検索条件に該当する文字列が有れば表示、無ければ非表示にすればいいだろう。

こうすると、該当要素の下位要素が表示されなくなってしまうのだが、俺の経験上、下から上に調査を進める時は、出発点よりも下位の情報は要らないんだよな。

逆に、上から下に調査を進める場合は、下位の要素を消しちゃ駄目なのだが、その場合はここで実装しようとしている機能ではなくて普通の文字列検索ができればいい。 HTAは実体がIEなので、IE同様に Ctrl+F で検索窓が表示される。

ということで doSearch() を実装する。

function doSearch() { try { var qry = getQryRegExp(); Array.prototype.forEach.call( document.getElementById( "base" ).getElementsByTagName( "div" ), function ( div ) { if ( qry.test( div.innerText ) ) { div.style.display = "block"; } else { div.style.display = "none"; } } ); } catch ( e ) { alert( e ); } function getQryRegExp() { var val = document.getElementById( "txtQuery" ).value; if ( !val ) { throw "ERROR : query"; } return new RegExp( val ); } }

簡単だな。

div内の検索対象を innerText にしているが、これは innerHTML だと色やフォントを変えるためのタグ、例えばspanなんかも検索対象文字列になってしまうから。

まだ属性名と属性値を色を変えて表示するようにはなってないが、そう遠くない未来、具体的には明後日ぐらいにそうする。 そうなったときに、検索条件を 「属性名="属性値"」 としてもちゃんと結果がとれるようにするには、タグが邪魔なのだ。

ついでに検索結果をリセットして全部の要素を表示する doReset() も実装する。

function doReset() { try { Array.prototype.forEach.call( document.getElementById( "base" ).getElementsByTagName( "div" ), function ( div ) { div.style.display = "block"; } ); } catch ( e ) { alert( e ); } }

さらに簡単。

定型的に try - catch を入れているが、さすがにこのレベルだと要らない気もするな。

実際に検索してみると、大きなファイルではそれなりに時間がかかるが、待てない程ではない。 しかし何度も繰り返すとイラっとするぐらいの、なかなか微妙な時間。 うーん…

あと、この仕様だと、親子にまたがった形で検索しようとすると、子供の方が表示されなくなる。

例えば 「要素Aの下に最初に定義されているのが要素Bのところ」 を検索するとき、検索条件を

<A>¥s*<B>

とすると、検索結果に要素Bは表示されない。

けどまあ、これは考え方次第か。 「Aの子の先頭がBになっているところ」 なら、検索結果として表示されているAの子供の先頭がBなのはもう判っていることだし、子の先頭がBじゃないAは表示されないし、わざわざBを表示する必要はないだろう。

いや、そんな言い訳じみた思考展開をしなくても、検索条件を 「子の先頭がBであるA」 と解釈すれば、この結果に何の問題も無いんだよな。 うん、無い。 決して開き直っているわけではない。

続きは明日。