プログラミング言語とXPath(3)

.NETでXPathを使うには、LINQ以前のSystem.Xml.XPath.XPathNavigatorクラスを使う方法と、LINQのXDocument, XElementに対してXPathSelectElementsなどのメソッドを使用する方法の二つがあるようです.

XPathNavigatorは言ってみれば、PCのワープロやエディタで文書を編集したり参照する場合の画面の「カーソル」のようなものです.XPathNavigatorは、様々な種類のMoveメソッドを持っていて、ちょうどカーソルが動くようにXML文書内をナビゲーションできます.それに加えて、Select([XPath式])メソッドを使ってノードをセレクトすることができます.

XPathNavigatorは、System.Xml.XPath.XPathDocumentクラスから、CreateNavigatorメソッドを使って生成します.XMLを読み込んで別物をつくるのだったら読み取り専用のXPathDocumentを使用するのでしょう.もしXMLを読み込んでそれを加工・更新して出力するのだったら System.Xml.XmlDocumentを使用します.

さてXPathDocumentクラスを使用して、以前と同じようにMusicLibrary.xmlから1994年発表のタイトルを表示するプログラムは以下のようになります.

Imports System.Xml
Imports System.Xml.XPath

Module Main

    Sub Main()
        Dim xpDoc As XPathDocument = New XPathDocument("MusicLibrary.xml")
        Dim xpNav As XPathNavigator = xpDoc.CreateNavigator()

        Dim xpExp As String = "/musicLibrary/cd[string(year) = '1994']/title"
        Dim xpNodeIter As XPathNodeIterator = xpNav.Select(xpExp)

        For Each title As XPathNavigator In xpNodeIter
            Console.WriteLine("The title is '{0}'", title.Value)
        Next
    End Sub

End Module

このプログラムを実行すると、以下のように'The Dark Side of the Moon'と表示されます.

イメージ 1

それでは一緒にそのアーティストも表示するのはどうすればよいのでしょうか?そのためには

        For Each title As XPathNavigator In xpNodeIter
            Console.WriteLine("The title is '{0}'", title.Value)
            Dim artistExp As String = "parent::*/artist"
            Dim artistIter As XPathNodeIterator = title.Select(artistExp)
            For Each artist In artistIter
                Console.WriteLine("The artist is '{0}'", artist.Value)
            Next
        Next

としてやればできます.つまりtitleの親のcdを求め、その子のartistを表示するのです.このプログラムの実行結果は以下のようになります.

イメージ 2

面白いのは、Selectメソッドを使って返されたXPathNodeIteratorの中身は、またXPathNavigatorであることです.XPathNavigatorもSelectメソッドを持っており、更にXPathを適用することができます.

次はLINQを使用した例を考えてみます.