2010年7月4日日曜日

◆XMLファイルを扱う

スクリプトの設定ファイルをXMLでというのはよくある。
こんな設定ファイルがあったとすると、

<config>
    <param1>1111</param1>
    <param2>2222</param2>
    <param3>3333</param3>
</config>

その読み込みは、

PS>$xml = [xml](Get-Content d:\desktop\config.xml)
PS>$xml.config.param2
2222

XMLタイプにキャストして参照するだけ。非常に簡単だ。

もうすこしXMLらしいサンプルを。

<Address>
    <Person type="Personal">
        <Name>佐藤</Name>
        <Phone>111-1111</Phone>
    </Person>
    <Person type="Business">
        <Name>吉田</Name>
        <Phone>333-3333</Phone>
    </Person>
</Address>

 

PS>$xml = [xml](Get-Content d:\desktop\sample.xml)
PS>$xml.Address.Person  |  ft -auto

type     Name Phone
----     ---- -----
Personal 佐藤 111-1111
Business 吉田 333-3333

PS>$xml.Address.Person[0].Name
佐藤


属性でクエリーすると

PS>$query = "/Address/Person[@type='Personal']/Name"
PS>$xml.SelectNodes($query)

#text
-----
佐藤


ちなみに、このプロパティは#textなんて名前になっているので、 XXXX.#textでは参照できない。
この場合は、以下のようにすると参照できる。

PS>$xml.SelectNodes($query) | Set-Variable node
PS>$node."#text"
佐藤

ただ、不思議なことに以下のようにすると結果が返ってこない。

PS>$node = $xml.SelectNodes($query)
PS>$node."#text"
PS>


これも駄目だ。

PS>($xml.SelectNodes($query))."#text"
PS>


なぜ?
意味が分からない・・・。
とりあえず逃げ道(Set-Variable)があるので放置(笑)

<追記>
PowerShell: ◆$a = $b と $a | set b の違い
,$node | gm  とやって$node自体のメンバーを確かめてみる。

PS>,$node | gm


   TypeName: System.Xml.XPathNodeList

Name          MemberType            Definition
----          ----------            ----------
ToString      CodeMethod            static string XmlNodeList(psobject instance)
Equals        Method                bool Equals(System.Object obj)
GetEnumerator Method                System.Collections.IEnumerator GetEnumerator()
GetHashCode   Method                int GetHashCode()
GetType       Method                type GetType()
Item          Method                System.Xml.XmlNode Item(int index)
ItemOf        ParameterizedProperty System.Xml.XmlNode ItemOf(int i) {get;}
Count         Property              System.Int32 Count {get;}

どうやらitemOfを使えばよさそうだ。

PS>$node.itemof(0)."#text"
佐藤

<追記おわり>

要素でもクエリーしてみる。

PS>$query = "/Address/Person[Name='吉田']/Phone"
PS>$xml.SelectNodes($query) | Set-Variable node
PS>$node

#text
-----
333-3333

PS>$node."#text"
333-3333

0 件のコメント:

コメントを投稿