はじめに
前回まではXmlDocumentオブジェクトを作成し、XMLデータを操作する方法について学んできました。今回からXPathNavigatorクラスを利用して、効率よくXMLデータを操作する方法について学びます。
サンプルのコードを動作させるには、記事に添付されている「population.xml」を使用します。必要に応じて「population.zip」をダウンロードし、解凍してお使いください。
対象読者
- Windows PowerShellの基本操作が行える方
- XMLについて基本知識を有する方
サンプルファイルについて
サンプルのpopulation.xmlは、県別の人口データを格納したファイルとなっています(説明用に作成したものです)。
データには、ルート要素として<population_data>、子として1つの県を表す<prefecture>要素があります。<prefecture>には属性districtがあり、これは地方を表しています。
また<prefecture>は子として県名を表す<name>と人口を表す<population>を持ちます。さらに、岩手県を表す要素には子要素として<municipality>を持ち、市町村名を表す<name>と人口を表す<population>があります。
構成は下記の通りです。
<population_data> <!-- ルート要素 --> <prefecture district="地方名"> <!-- 1つの県を表す --> <name>県名</name> <population>人口</population> <municipality> <!-- 岩手県のところだけにある要素 --> <name>市町村名</name> <population>人口</population> </municipality> </prefecture> </population_data>
XPathNavigatorクラスとXPath言語について
XPathNavigatorクラスはXML Path言語を使用して、XML データ内を移動したり XML データを編集したりということを容易に行うことができます。ではXML Path言語とはなんでしょうか?
XML Path言語(以降、XPath)は、URLで使用されているようなパス表記法を用いたXML専用のクエリです。前回までに紹介したXmlDocumentオブジェクトでは、データを取得するのに「xxの要素のyy要素」のように、1つ1つ階層を指定したデータの取り出しを行う必要がありました。しかし、XPathを用いれば少ない操作で特定の要素の取り出しや編集が行えるようになります。
XPathNavigatorオブジェクトの作成
XPathNavigatorオブジェクトはXmlDcumentやXPathDocumentから作成することができます。今回はXmlDocumentから作成します。
まず下記のようにしてサンプルのXMLファイルを読み込み、XmlDocumentオブジェクトを作成します。
PS> $xmlDoc = [xml](Get-Content population.xml -Encoding UTF8)

次に、今作成した$xmlDocからCreateNavigator()メソッドを使用して、XPathNavigatorオブジェクトを作成します。
PS> $Navi =[Xml.Xpath.XPathNavigator] $XmlDoc.CreateNavigator()

XMLデータの選択
XPathNavigatorの基本使用方法
作成したXPathNavigatorオブジェクトを使用してデータを選択するにはSelect()メソッドを使用します。このメソッドには引数としてXPath式を指定する必要があります。
またSelect()メソッドの結果はXPath式でヒットしたノードのセット(XPathNodeIterator)を返します。このノードを1件ずつ処理する場合にはMoveNext()メソッドを使用した取り出しが有効です。
以下に基本的な使用方法を示します。
# XPathを使用してノードを取得
$nodes = $navi.Select(XPath式)
# MoveNext()メソッドによる値の取り出し
While ( $nodes.MoveNext() )
{
#ここに各要素を処理するコマンドを記述
}
次にWhile() { ~ }内で各ノードにアクセスする方法について説明します。While() { ~ }内では処理中のノードはCurrentで表されます。また要素名は$nodes.Current.Name、要素の値は$nodes.Current.Valueでアクセスすることができます。
MoveNextメソッドでデータを取り出すとその変数の中身(ここの例では$nodes)は空となり、2度目以降の取り出しは行うことができないので注意が必要です。
