Internet Explorer 6.0からはじめるXML


 
Internet Explorer は何物?
 

 国民機と言われたPCが圧倒的に支持された時代があった。いまだに その環境を一台の486マシ−ンで使えるようにしている。そこでは、「おもちゃ」と言われたInternet Explorer 2.0が生きている。僕のLANはPC博物館かもしれない。
 実際に使い始めたInternet Explorer は3.0。雑誌の付録CDよりインストールした。すごいソフトが無料なのには驚いた。かって、ベーターと VHSの戦争があった。MSはその歴史を徹底的に分析し学んだという。 知らなかったのだが、NetscapeとMicrosoft のブラウザ戦争が勃発していた 訳だ。
 戦争の余波でブラウザが無料で手に入る。自国に爆弾が落ちない時は、 戦争はありがたい。第一次世界大戦の時の日本がそうであった。 第二次世界大戦の合衆国がそうであった。20世紀は戦争の世紀だったが、フラッグを掲げ威風堂々の地上戦は、もうドンキホーテ の幻想なんだよ。
 戦争の余波で無料ブラウザの恩恵だけを享受できたわけでもない。あっという間に広がるワームの為に被爆した人は多いだろう。僕も自衛の為に やむをえずInternet Explorer は6.0にした。もう5.0以上がブラウザの90% と考えていいのだろう。結果論なのだが、ワームが果たした役割は 大きい。

 
XMLバーサ
 

 21世紀はXMLの時代。XMLを理解するには1枚のペ−ジを読めば 事は足りる。だが、XMLは憲法。実体法の民法を熟知しないと法律で飯 は食えない。それと同じように、XMLで何が出来るの?

  XMLでは何もできない。XMLの精神を神に誓い守ると宣言した ワープロを手に入れる必要がある。

 「ワープロ」はもう過去のキーワードだが、Parser が次世代キーワード。パーサと読むのだろうが小さなフオントを使っているのでバーサと認識してしまった。サーバのミラー文字でバーサ、なかなかしゃれてると感心してしまった。「コーヒー」と「カフェ」とどちらが正解?公式 サイトがこちらですよと言うのだろうが、僕は構わず、しゃれっ気を活かして バーサと一生呼ぶ事にしようか。
 Internet Explorer6.0をインストールするとMsxml3.dllがPCのwindows/systemに組み込まれる。知らなかった。PCの中を検索すると Msxml3.dll、Msxml3a.dll、Msxml3r.dllのセットである。もう一組、3のない のもある。IEのバージョンアップのたびにMsxmlも変身して、いまでは4が最新らしい。とりあえず3を有効にしよう。
 レジストリーを書き換えないと古いMsxmlしか動かない。レジストリー書換えツールをMSダウンロウドサイトで手に入れる(Keywordsにxmlinstと入力しgo)。DOSプロンプトでxmlinst.exeを実行する。これでMsxml3の環境になる。 Msxml、Msxml2、Msxml3の環境は自分で選択して構築できる。regsvr32.exeを使う。これも知らなかったのだが、regsvr32.exeはwindows/systemに組み込まれていた。引数としてMsxml、Msxml2、Msxml3を指定してDOSプロンプトで実行する。xmlのない環境も作れる。詳細は添付のreadmeに書いてある。

MSXML3はXMLパーサ、DOM、SAX、XSLTの機能を提供する。

 当面、これだけあればXMLは事足りる。無料XMLパーサで、次はOracleとMicrosoftのXML戦争なのだろうか。そろそろ日の丸を戦場に掲げなくては。自衛艦を海外に向けることがShow the flageではないはずだ。

 

オブジェクトとメソッドとプロパティ
 

 javaScriptはオブジェクト指向言語。例えば、このページを javaScriptで操作するとして、このページ自体が documentというオブジェクト。OSのwindowというオブジェクトの上にある。  変数mojiを作る。それもオブジェクト。「プロパティ」、つまり「特徴」を持つ。moji.fontsize(2)で文字のサイズを操作出来る。
 オブジェクトには階層構造があって、上位から、
ウィンドウフレームドキュメントフォームエレメント
の順である。
 何か目的があってjavaScriptを扱い出せば、こんな程度は理解できる。しかし、基本を押さえないと行き詰まる。 ネットで検索して大半解決するのだが、何かスッキリしない。
  JavaScriptと JScriptがあり、NetscapeとMicrosoftの独自dynamicHTMLがあった。 検索ではそれらが、ごっちゃにリストアップされる。少し混乱してしまう。 いつもそうなのだが、戦争の勝利者が責任をもって地雷除去をしたことはない。ネットの情報の価値は個人の責任で選別しなければならない 。

どうもDOMが決め手のようだ。

 

DOM
 

Document Object Model (DOM)
DOM1 日本語版
DOM-Level-2-Core

 DOMは,XML文書をオブジェクト化するルールを明記したもの,それにアクセスするためのインターフェイスのルールも記述している。インターフェイスという手法はIBMが大型コンピュータをコストダウンする段階で利用した。接続のルールを公開して多様なパーツを利用できるようにした。コンセントの規格を統一しておけば、消費者はどこのメーカーの電化製品でも購入できる。そう言えば分り易い。XML文書がこのDOM仕様であれば、NetscapeでもMicrosoftでも意識せずScriptを書ける。独自dynamicHTMLの不便さを乗り越えるものと思えばいい。dynamicHTMLのことはもう忘れよう。

コア部分
 ここのルールはXMLと表明するなら、すべて守らなければならない。
  1.1.1. The DOM Structure Model
オブジェクトは階層構造を持つ。系統図のような世界でオブジェクトを「Node」と呼ぶ。子供を持てないNodeもある。 NodeList というサービスがある。どこかで子供が生まれたら、即座に リストに反映されなければならない。それでないとXMLではありえない。.....じゃあ、住民台帳はXMLじゃないか。

HTML部分
 HTMLで定義されたエレメントの機能についてのルール。

  2.2.1. 命名上の慣習
名前
1語以上の英単語が結合されて単一の文字列となったものとする。
先頭は小文字のキーワードで始まり,後続の単語はそれぞれ大文字で始まる。
............
............


 JavaScriptで何をするんだ。XMLデーターからAutoCAD用のスクリプト を作りたい。XMLにアクセスするコマンドが欲しいんだな。そうです。 と言い聞かせてDOMを読む。
 斜め読みして必要な部分だけ参照。dynamicHTMLはもう忘れる。 XMLを操作するJavaScriptを書くのだが、DOMのルール, すなわち、XML仕様コマンドを使う。今、必要なのはこれだけ。

 

DOM仕様コマンド
 

   JavaScriptでXMLファイルからデーターを読み込む。そのため、 まずオブジェクトを用意する。このHTMLページ上のJavaScriptで XMLを読み込むことになるが、documentというオブジェクトはそのページ自身。 それ以外に、xml用のオブジェクトを作る。名前はxmlのルールに従い 自由に付ける。
var xmlDoc= new ActiveXObject("Microsoft.XMLDOM");
 IEでJavaScriptだから正確にはJScriptを利用している。オブジェクトはActiveXObjectを利用する。DOMは何から何まで規定をしない。便利なものはベンダー独自仕様を使う。それでいいと思う。ActiveXObject作成法はMSのページ参照(メモ)。
xmlDoc.async = false; xmlDoc.load("../freedata/23220GK.xml");
 loadはメソッド。MicrosoftXMLパーサがインストールしてあるので有効。XML文書をオブジェクトとしてメモリーに データー展開してくれる。一つのXML文書に一つのdocument を作り、その下にElementを系図状に管理している。
 XMLのソースを眺めれば分るのだが、タグ付きデータ=エレメントが階層構造で並べてある。これはxmlのルール。これら全体をドキュメントと呼ぶ。 眺めたり、データとして抜き取ったり、削除修正するにはアクセスできなければならない。JavaScriptはオブジェクト指向言語だから当然オブジェクトの階層構造にする。要素には属性があった。属性は要素の付属物だから、要素と属性は対等関係ではない。しかし、まずはなんでもnodeというオブジェクトにしてしまおう。これがDOMの発想のようだ。
 xmlにはルート要素があった。これがdocumentElementに対応する。
documentElement.nodeName
documentElement.childNodes.length
documentElement.childNodes.item(0).nodeName
documentElement.childNodes.item(1).nodeName
オブジェクト言語だからプロパテーをこの様に指定する。

 ルート要素のnodeNameを確認して、その直下のnode数をしらべ、 直下のnode(=子node)の名前を確認する。それを文字列に 取出して表示してみる。
string="root node = "+xmlDoc.documentElement.nodeName+"\n"; string+="root node length= "+xmlDoc.documentElement.childNodes.length+"\n"; string+="root node itim(0)= "+xmlDoc.documentElement.childNodes.item(0).nodeName+"\n"; string+="root node itim(1)= "+xmlDoc.documentElement.childNodes.item(1).nodeName+"\n";
 国土地理院の数値地図25000は、GIというルートelementの下に、exchangeMetadataとdatasetの2つのブロックがある。exchangeMetadataはクリアハウスデーター。地図データはdatasetに格納されている。

 datasetのnodeNameを確認して、その直下のnode数をしらべ、 直下のnodeの名前を確認してみる。

currNode = xmlDoc.documentElement.childNodes.item(1)
currNode.nodeName
currNode.childNodes.length
currNode.childNodes.item(0).nodeName
currNode.childNodes.item(1).nodeName
currNode.childNodes.item(1).text
currNode.childNodes.item(2).nodeName
currNode.childNodes.item(3).nodeName
currNode.childNodes.item(4).nodeName
............
............
2番目の子供elementはコメントだった。その内容はtextで取り出せる。

 ルートから辿ればアクセス出来るが、気が遠くなる。ビジネスツールはもっとスマートなはず。nodeの名前は要素の名前、つまりタグ名ということ。ならば、タグ名で検索ができるはずだ。

この場合getElementsByTagName()を使いリストを作る。

objNodeList = xmlDoc.getElementsByTagName("GyoseiKai")

変数objNodeListに代入して、りっぱなオブジェクトになる。
objNodeList.nodeNameは定義されていないと回答がある。
getElementsByTagName()で作成されたnodeはPCのメモリー上のもの。具体的なタグ名がないので未定義ということだろう。
nodeListに拾い出されているitem()は一人前のnode。というより、nodeListはオリジナルなnodeの仮集計票という感じだ。item()を通じてオリジナルnodeにアクセスするということ。
objNodeList = xmlDoc.getElementsByTagName("GyoseiKai"); string+="node length = "+objNodeList.length+"\n"; string+="node item(0) = "+objNodeList.item(0).nodeName+"\n"; string+="node item(0).text = "+objNodeList.item(0).text+"\n"; string+="node item(1) = "+objNodeList.item(1).nodeName+"\n"; string+="node item(1).childNodes.length = "+objNodeList.item(1).childNodes.length+"\n"; string+="node item(1).childNodes.item(0).nodeName ="+objNodeList.item(1).childNodes.item(0).nodeName+"\n"; string+="node item(1).childNodes.item(0).text ="+objNodeList.item(1).childNodes.item(0).text+"\n"; string+="node item(1).childNodes.item(1).nodeName ="+objNodeList.item(1).childNodes.item(1).nodeName+"\n"; string+="node item(1).childNodes.item(1).text ="+objNodeList.item(1).childNodes.item(1).text+"\n"; string+="node item(1).childNodes.item(2).nodeName ="+objNodeList.item(1).childNodes.item(2).nodeName+"\n"; string+="node item(1).childNodes.item(2).text ="+objNodeList.item(1).childNodes.item(2).text+"\n";

 GyoseiKai要素はJotai、Shurui、curveの要素で構成されている。その内容はtextで取り出せる。curveはさらにCRS、segment、controlPointの要素に細分化されている。curveのtextでデーターを取り出すと、CRSはコメント的な要素で値がないからいいが、controlPointはぞろぞろ繋がってしまう。

 実質GyoseiKai要素はcurve要素で取り出せばよい。curve要素の孫要素segmentに結線データがまとめらている。
curve要素を現在nodeとして,その子供要素childNodes.item()はchildNodes[]とまとめて書ける。 childNodes[].childNodes[]とすれば孫要素を指定できる。普通子供は沢山いるので0、1、2と番号をつけて利用する。

 controlPointのデーター抽出はwhileループで自動実行。これを完成してXMLデーターからCAD用データーの抽出は見通しがついた。


 

DOMによるXMLデーター処理
 

[ファイルタイプ選択]
XML ..23220GKのXMLファイル
HTML ..23220GKのHTMLファイル----タグ解釈ナシ(xmp)

DOM nodeの確認
....




 Msxmlを利用したXMLデータファイル処理サンプル。エデイタで切った張ったをするより、このほうがスマートでしょう。

2003.11.08
by Kon