プログラミング言語とネームスペース(4)

F#の例を紹介します.XPathを使用する場合はほとんどVBと同じです.XmlNamespaceManagerクラスを生成して、接頭辞とネームスペースを必要なだけ登録します.XmlNamespaceManagerクラスは、XPathSelectElementsメソッドを実行するときに指定します.

open System.Xml.XPath
open System.Xml.Linq
open System.Xml

[<EntryPoint>]
let main argv = 
    let xd = XDocument.Load("MusicLibraryNS.xml")
    (* XPathSelectElementsを使うやり方*)
    let nt:NameTable = new NameTable()
    let nsm = new XmlNamespaceManager(nt)
    nsm.AddNamespace("mlp", "uri:music:library")
    nsm.AddNamespace("cdp", "uri:music:cd")
    nsm.AddNamespace("ttlp", "uri:music:title")
    let titles = xd.XPathSelectElements("mlp:musicLibrary/cdp:cd[string(mlp:year) = '1994']/ttlp:title",nsm)
    let showTitle = 
        for title in titles do 
            printfn "The title='%s'" title.Value
    0

Linqの軸メソッドを使うやり方は次のようになります.VBより少し複雑です.

open System.Linq
open System.Xml.Linq
open System.Xml

[<EntryPoint>]
let main argv = 
    let xd = XDocument.Load("MusicLibraryNS.xml")
    (* LINQ to XMLのAxis Methodを使うやり方 *)
    let mlns = "uri:music:library"
    let cdns = "uri:music:cd"
    let ttlns = "uri:music:title"
    let xn ln ns = XName.Get(ln,ns)
    let queryTitles = 
        xd.Elements(xn "musicLibrary" mlns)
          .Elements(xn "cd" cdns)
          .Where(fun (cd:XElement) -> cd.Element(xn "year" mlns).Value.Equals("1994"))
          .Elements(xn "title" ttlns)
    for title in queryTitles do 
        printfn "The title='%s'" title.Value
    0

VBだとElementsメソッドをElement(mlns + "musicLibrary")とかけたのですがF#では、明示的にxnという関数を呼び出してやらねばなりません.VBのときに何気なく書いていたElement()の引数は実はXNameクラスのオブジェクトです.XNameは要素や属性の名前を表します.ですのでXMLのQName(修飾名)をインプリメントしたクラスと考えて良いでしょう.

XNameはコンストラクタを持たず、XName.Get(ローカル名, 名前空間)から、XNameクラスのインスタンスを返してくれます.ですので

let xn ln ns = XName.Get(ln,ns)
let mlns = "uri:music:library"
let xname = xn "musicLibrary" mlns

と書けばxnameはローカル名が"musicLibrary"、名前空間が"uri:music:library"のXNameを表してくれます.VBの場合は、mlns + "musicLibrary"で自動的にXNameにキャストしてくれるようなのですが、F#はそうはいきません.明示的に変換関数を入れてやる必要があります.

次はScalaの例を紹介したいと思います.