3.25.2012

Parsing XML file with VBScript

VBScript: XMLファイルの読み取り

VBScript による XML ファイルの読み取り方法の一例を記載する。

1. 使用するXMLファイル

 ・shogi.xml

<?xml version="1.0" encoding="Shift_JIS"?>
<shogi version="0.1">
  <turn>+</turn>

  <board place="51"><piece turn="-" type="OU" /></board>
  <board place="59"><piece turn="+" type="OU" /></board>
  <board place="77"><piece turn="+" type="FU" /></board>

  <hand>
    <piece turn="+" type="FU">3</piece>
    <piece turn="-" type="KY">2</piece>
  </hand>
</shogi>

 将棋のある局面における手番、盤上の駒、持ち駒を表現。
 構造を図で表すとこのようになる。

image

2. 実装手順

 (1) XMLファイルのロード

   まず、CreateObject で Msxml2.DOMDocument オブジェクトを作成。
   async プロパティを False に設定して非同期モードとする。
   そして、XMLファイルのパスを指定して load すればよい。

Set xmlDoc = CreateObject("Msxml2.DOMDocument")
xmlDoc.async = False
xmlDoc.load "path_to_the_xml_file"

   XML解析の成否判定は、load メソッドの戻り値または parseError.errorCode プロパティの参照により行う。
   例外は送出されない。

 (2) 単一要素の取得

   要素が1つだけであることがわかっている場合は、selectSingleNode メソッドでそのノードの参照を取得できる。
   パラメータに指定するのは、XPath 式の文字列。
   ノードが末端である場合、text プロパティを利用することでその値を取得できる。
   例えば、「turn」の値はこのように取得できる。

xmlDoc.selectSingleNode("/shogi/turn").text

 (3) 属性の取得

   XPath式で属性名の前に「@」を付ければ、要素と同じ方法で値を取得できる。
   「version」の取得はこのような形だ。

xmlDoc.selectSingleNode("/shogi/@version").text

   子ノードの参照を別の変数に保存すれば、このように相対パスで値を取得することもできる。

Set xmlShogi = xmlDoc.selectSingleNode("/shogi")
xmlShogi.selectSingleNode("@version").text

   ただし、ノードに指定されている属性を取得する方法として、getAttribute メソッドが用意されている。
   これが一番簡単だ。

xmlShogi.getAttribute("version")

 (4) 複数要素の取得

   同じ名前の要素が複数存在する場合は、selectNodes メソッドで要素のコレクションを取得できる。
   For Each … In … 構文を利用すれば、全ての要素に対して処理を行うことが可能だ。

For Each xmlBoard In xmlShogi.selectNodes("board")
  (各 xmlBoard に対する処理)
Next

3. コード

XMLファイルの内容を表示するスクリプト。cscript での実行を前提とする。

・xml_sample.vbs

' Must run in CScript.
If LCase(Right(WScript.FullName, 12)) <> "\cscript.exe" Then WScript.Quit 1

' Load XML file.
Const kXMLPath = "shogi.xml"

Set xmlDoc = CreateObject("Msxml2.DOMDocument")
xmlDoc.async = False
xmlDoc.load kXMLPath
If xmlDoc.parseError.errorCode <> 0 Then Err.Raise 1, , _
    "Failed to load XML file [" & kXMLPath & "]: " & xmlDoc.parseError.reason

' Get single node.
WScript.Echo "turn: " & xmlDoc.selectSingleNode("/shogi/turn").text

' Get attribute.
WScript.Echo "version: " & xmlDoc.selectSingleNode("/shogi/@version").text

Set xmlShogi = xmlDoc.selectSingleNode("/shogi")
WScript.Echo "version: " & xmlShogi.selectSingleNode("@version").text

WScript.Echo "version: " & xmlShogi.getAttribute("version")

' Get all nodes.
For Each xmlBoard In xmlShogi.selectNodes("board")
  Set xmlPiece = xmlBoard.selectSingleNode("piece")
  WScript.Echo "board " & xmlBoard.getAttribute("place") & ": " & _
      xmlPiece.getAttribute("turn") & _
      xmlPiece.getAttribute("type")
Next

For Each xmlHand In xmlShogi.selectNodes("hand")
  For Each xmlPiece In xmlHand.selectNodes("piece")
    WScript.StdOut.Write "hand: " & xmlPiece.getAttribute("turn")

    For i = 1 To CInt(xmlPiece.text)
      WScript.StdOut.Write xmlPiece.getAttribute("type")
    Next
    WScript.Echo
  Next
Next

4. 出力結果

turn: +
version: 0.1
version: 0.1
version: 0.1
board 51: -OU
board 59: +OU
board 77: +FU
hand: +FUFUFU
hand: -KYKY

参考:
http://msdn.microsoft.com/en-us/library/aa468547.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms762722%28v=vs.85%29.aspx

IXMLDOMNode インターフェイス
http://msdn.microsoft.com/ja-jp/library/aa948719%28v=office.11%29.aspx

0 件のコメント:

コメントを投稿