怠日記

写真・金魚・昆虫・プログラミングの趣味を語るサイトです。似たようなことをnoteにも書いたり書いてなかったり。

VBScript - XML を読み込む

データベースの接続先やメールの通知先など、設定値を外部ファイルに持たせたいときがある。

VBA であれば Ini ファイルが使えるが、VBScript には Ini ファイルを扱う機能はない。

そんなときは XML で管理すると便利。

VBScriptXML を扱うには MSXML2.DOMDocument オブジェクトを使う。

XML の読み込み

XML を扱うには、まず XML をオブジェクトに読み込む必要がある。

ファイル、または文字列の XML を読み込める。

どちらから読み込んだとしても、読み込み後は同じように使える。

XML ファイルを読み込む

XML ファイルを読み込むときは load メソッドを使う。

load メソッドは読み込みに成功すると True を返すので、True のときのみ処理する。

With CreateObject("MSXML2.DOMDocument")
    If .load("C:\path\to\file.xml") Then
        'TODO: 読み込み成功時の処理を書く
    End If
End With

文字列の XML を読み込む

文字列の XML を読み込むときは loadXML メソッドを使う。

load メソッドと同じく、読み込みに成功すると True を返すので、True のときのみ処理する。

Dim xml
xml = "<?xml version=""1.0"" encoding=""utf-8""?><configuration> ... 省略 ... </configuration>"
With CreateObject("MSXML2.DOMDocument")
    If .loadXML(xml) Then
        'TODO: 読み込み成功時の処理を書く
    End If
End With

読み込みに失敗した理由を取得する

parseError プロパティよりエラーコードと理由が取得できる。

errorCode がエラーコード、reason がエラーの理由。

*読み込み成功時の値は、errorCode が 0 、reason は空文字になる。

With CreateObject("MSXML2.DOMDocument")
    If .load("C:\path\to\file.xml") Then
        'TODO: 読み込み成功時の処理を書く
    Else
        '読み込みエラーの内容を表示する
        WScript.Echo CStr(.parseError.errorCode) & ": " & .parseError.reason
    End If
End With

たとえば存在しないファイルを読み込もうとした場合、以下の内容が表示される。

-2146697211: 指定されたリソースが見つかりません。

XML の解析(ルート要素から順番に読み取る方法)

以下のスクリプトは、読み込んだ XML をルート要素から順に読み取る。

ルート要素を DisplayData プロシージャに渡し、XML の内容を表示している。

With CreateObject("MSXML2.DOMDocument")
    If .load("C:\path\to\file.xml") Then
        DisplayData .childNodes
    End If
End With
Sub DisplayData(nodes)
    Dim item
    For Each item In nodes
        '要素を表示する
        WScript.Echo item.nodeType, item.nodeName, item.nodeValue
        
        '要素の属性を表示する
        If Not item.attributes Is Nothing Then
            Dim atrb
            For Each atrb In item.attributes
                WScript.Echo vbTab, atrb.nodeType, atrb.name, atrb.text
            Next
        End If
        
        '子要素があればその内容を表示する
        If item.hasChildNodes Then
            DisplayData item.childNodes
        End If
    Next
End Sub

nodeType プロパティ

ノードの種類を表す。

nodeType プロパティの主な内容は次のとおり。

  • NODE_ELEMENT(1): 要素
  • NODE_ATTRIBUTE(2): 要素の属性
  • NODE_TEXT(3): 要素のテキスト
  • NODE_PROCESSING_INSTRUCTION(7): 処理命令(?> で囲まれた文のこと)
  • NODE_COMMENT(8): コメント
  • NODE_DOCUMENT_TYPE(10): ドキュメントタイプ宣言(例:

nodeName プロパティ

要素名を取得する。

nodeValue プロパティ

要素の値を取得する。

text プロパティ

要素が持つテキストを取得する。

childNodes プロパティ

子要素のコレクションを取得する。

hasChildNodes メソッド

子要素があるかどうかを返す。

XML の解析(XPath 式を使って目的のデータを読み取る方法)

XML の構造が分かっている場合、XPath 式を使って目的の要素からデータを読み取ることもできる。

ルート要素からたどっていく必要がないので、XPath 式を使う方が効率的。
ただし前述のとおり、XML の構造が分かっていないと使えない。

With CreateObject("MSXML2.DOMDocument")
    If .load("C:\path\to\file.xml") Then
        'XPath 式で取得
        Dim nodeList
        Set nodeList = .documentElement.selectNodes("/configuration/appSettings/add[@key='Text']")
        '取得した結果を表示
        Dim item
        For Each item In nodeList
            WScript.Echo item.nodeType, item.nodeName, item.Text
        Next
    End If
End With

selectNodes メソッドは、指定された XPath 式に該当する要素のコレクションを返す。

その後のループで、要素のコレクションを順に取得し、内容を表示している。

XPath 式のサンプル

次の XML から XPath 式を使ってデータを取得してみる。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <connectionStrings>
    <add name="DB1" connectionString="User Id=john; Password=1234; Data Source=db1.world" />
    <add name="DB2" connectionString="User Id=scott; Password=tiger; Data Source=orcl" />
  </connectionStrings>
  <appSettings>
    <add key="Host">example.com</add>
    <add key="Port">25</add>
    <add key="MailAddress">user@example.com</add>
  </appSettings>
</configuration>

要素の指定方法

/要素名 で指定する。

例)/configuration/appSettings

configuration 要素→ appSettings 要素の配下にあるすべての要素を取得する。

例)/configuration/appSettings/add

configuration 要素→ appSettings 要素の配下にある add 要素を取得する。

属性の指定方法

/要素名[@属性名] で指定する。

例)/configuration/appSettings/add[@key]

configuration 要素→ appSettings 要素の配下にある add 要素で key 属性を持つ要素を取得する。

(属性値は見ないため、key 属性の値は何でも良い)

属性値の指定方法

/要素名[@属性名='属性値'] で指定する。

例)/configuration/appSettings/add[@key='MailAddress']

configuration 要素→ appSettings 要素の配下にある add 要素で key 属性が “MailAddress” である要素を取得する。