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

Scalaでネームスペースを使う例を紹介します.

まずいままでVBやF#でネームスペースを扱うのにそれなりの「儀式」をしてきました.ところがScalaでは、


でネームスペースをつけたMusicLibraryNS.xmlを処理しようとして次のように書くと、なんの問題もなく動いてしまいます.

def main(args: Array[String]) {
  val root = XML.loadFile("MusicLibraryNS.xml")
  val titles = (root \\ "musicLibrary" \ "cd").filter(cd => (cd \ "year").text =="1994") \ "title"
  titles.foreach(title => println("The title='" + title.text + "'"))
}

これには正直がっかりです.つまりどういうことかというと、他の言語はちゃんとXMLのQNameを要素を絞り込む条件として記述できたのですが、ScalaにはQNameの概念が「ない」ということなのです.上記のプログラムは要素のローカル名を指定しています.ローカル名の指定を正確に出来れば、ネームスペースがどうなっていようがプログラムは動いてしまうのです.ではネームスペースをちゃんと考慮したバージョンはどのように作るのでしょうか?ネームスペースを別途フィルターしてやらねばなりません.以下のように結構複雑になります.

def main(args: Array[String]) {
  val nsml="uri:music:library"
  val nscd="uri:music:cd"
  val nsttl="uri:music:title"
  val root = XML.loadFile("MusicLibraryNS.xml")
  val titles = (((root \\ "musicLibrary").filter(cd => cd.namespace == nsml) \ "cd").filter(cd => cd.namespace == nscd && *1.text =="1994") \ "title").filter(title => title.namespace == nsttl)
  titles.foreach(title => println("The title='" + title.text + "'"))
}

ここでnamespaceは、def namespace: Stringと定義されています.要素のネームスペースを返してくれるメソッドです.


つまりネームスペースも含めて厳格に要素を選択するにはいちいちfilterメソッドを入れてやらねばならないようです.これでは本格的には使えない気がします.なんらかの解決方法はないのでしょうか?すこしScales XMLを使った場合にどうなるのかを調べてみたいと思います.

*1:cd \ "year").filter(year => year.namespace == nsml