Scalaでネームスペースを使う例を紹介します.
でネームスペースをつけたMusicLibraryNS.xmlを処理しようとして次のように書くと、なんの問題もなく動いてしまいます.
def main(args: Array[String]) {
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 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