javaScript



 
XMLファイルのデータ加工
 

     
 XMLファイルも結句はtxtファイル。テキストデータとして必要なデータを抽出してみる。DOS時代のシーケンシャルファイルの扱い方で処理する。          
<DoroKukan id='DK23220006464'> <Jotai>供用中</Jotai> <Yuryo>無料</Yuryo> <Shubetsu>一般道</Shubetsu> <Fukuin>1.5m以上3.0m未満</Fukuin> <Namae></Namae> <curve id='CV23220006565'> <CRS idref='JGD2000'/> <segment> <controlPoint>492422.7870 126881.6600</controlPoint> <controlPoint>492422.7130 126880.0780</controlPoint> <interpolation>linear</interpolation> </segment> </curve> <edge id='EG23220000043'> <boundary idref='ND23220002500'/> <boundary idref='ND23220002498'/> <geometry idref='CV23220006565'/> </edge> </DoroKukan>      

 これが数値地図25000の道路区間データ。頭にヘッダー情報が付いているが、中間はこのパターの膨大な繰り返し。

 
Scripting.FileSystemObject
 
 解凍したファイルがローカルなPCに保存されているとする。地図番号にDK.xmlとしたファイルをTXTSTREAMオブジェクトとしてjavaScriptで操作する。マイクロソフトのJScriptは以下の機能があるので利用する。          
var xDrv = new ActiveXObject("Scripting.FileSystemObject"); var dataFile = xDrv.OpenTextFile(dname+mapno+mapfile+".xml",1 ); -------中間処理------ msg=dataFile.ReadLine() -------中間処理------  dataFile.Close();      
 一行順次読込む時のコードパターンは、このようになる。


 
抽出ロジック
 

 処理は次ぎのステップの繰り返し。
  • DoroKukan id='DK23220006464'まで読み飛ばす。この行に着いたらidを抽出、画層名とする。
  • Fukuinまで読み飛ばす。この行で幅員を決める。
  • controlPointまで読み飛ばし、中心点を抽出、緯度経度からXYに変換。
  • controlPointタグの間、この作業を続ける。
  • controlPointでなくなったら、次のループに行く。

 
ループコード
 

中間処理はWHILE文を使う。
       
key="<DoroKukan id="; key2="</DoroKukan>"; if (dorohaba=="1.5") {key3="1.5m未満";layerColor="53";} if (dorohaba=="3.0") {key3="1.5m以上3.0m未満";layerColor="31";} if (dorohaba=="5.5") {key3="3.0m以上5.5m未満";layerColor="30";} if (dorohaba=="13") {key3="5.5m以上13.0m未満";layerColor="22";} if (dorohaba=="25") {key3="13.0m以上";layerColor="14";} if (dorohaba=="30") {key3="真幅道路等";layerColor="16";} var ID=new String;; var msg2; var fukuin=dorohaba; while (!dataFile.AtEndOfLine) { msg=dataFile.ReadLine(); while ( ( n1=msg.indexOf(key,0) ) == -1) {msg=dataFile.ReadLine();} ID=msg.substring(n1+key.length+1,n1+key.length+14); while ( ( n2=msg.indexOf("<Fukuin>",0) ) == -1) {msg=dataFile.ReadLine();} n3=msg.indexOf("</Fukuin>",0); if (msg.substring(n2+8,n3) == key3 ) { outMSG.WriteLine("-layer"); outMSG.WriteLine("M"); outMSG.WriteLine(ID); msg2="C"+"\r\n"; msg2+=layerColor+"\r\n\r\n\r\n"; msg2+="dline\r\n"; msg2+="w\r\n"; msg2+=fukuin; outMSG.WriteLine(msg2); while ( ( n2=msg.indexOf("<controlPoint>",0) ) == -1) {msg=dataFile.ReadLine();} n3=msg.indexOf("<controlPoint>",0); xy=msg.substring(n3+14,n3+37).split(" "); xx=parseFloat(xy[0]); yy=parseFloat(xy[1]); ramu=xx/648000*PI; phai=yy/648000*PI; bl2xy(); msg2=yy+","+xx+",0.00"; outMSG.WriteLine(msg2); while (true) { msg=dataFile.ReadLine(); n3=msg.indexOf("<controlPoint>",0); if (n3==-1) {outMSG.WriteLine();break;} xy=msg.substring(n3+14,n3+37).split(" "); xx=parseFloat(xy[0]); yy=parseFloat(xy[1]); ramu=xx/648000*PI; phai=yy/648000*PI; bl2xy(); msg2=yy+","+xx+",0.00"; outMSG.WriteLine(msg2); } } } dataFile.Close(); outMSG.Close();      

 条件文( ! dataFile.AtEndOfStream) はファイルの最終行の時、真(true)。 !  で否定しているので、最終行までReadLine()が繰り返される仕組み。最終行になったら、 ループを抜け出し、ファイルをClose()してくれる。
 WHILE文の条件判定はループの作業開始時点の判断。途中で最終行を飛び出すコード を書くとエラー終了になる。途中に判定ルーチンでbreakさせることが必要。
 ループの作業を一度してから判断するDOを使うのがいいのかも知れない。


マイクロソフトのjScriptリファランス


2003.12.19
by Kon