ScalaでXML

ちょっと触る(&ハマる)機会があったので、あちこちに既出だとは思いますが、ScalaでのXML操作についていくつか纏めてみたいと思います。誰かのお役に立てれば。

ScalaではXMLの扱いが簡単!」という言い方は、嘘ではないのですが、恐らく他の処理系にはない「癖」があるので、それを飲み込む必要があります。(「他の処理系」にあまり詳しくないので歯切れ悪いのですが、、)

まずは便利な点から。

XMLリテラルの記述

ScalaではXMLリテラルが型として組み込まれていて、特にライブラリを追加することなく扱うことができます。次のような感じ。

	private val Xml =
		
			element1
			element2
			
				child1
			
		

XPath記法

そして、次のような簡潔な方法で要素にアクセスすることができます。

println(Xml \ "element")

これの出力結果は以下の通り。

element1element2
				child1
			

改行については敢えて崩れたまま記載しています。そういう内容が出力されるので。

さらに今回色々悩んだ部分も含めて、ソースコードをがさっと掲載します。

object XMLWork {
	
	private val Xml =
		
			element1
			element2
			
				child1
			
		
	
	private val XmlWithNS =
		
			element1
			element2
			
				child1
			
		
		
	def main(args : Array[String]) : Unit = {
		println("・絶対パス指定はルート要素を省いてしまう")
		println(Xml \ "root")
		println("・つまり絶対パス指定は2段階目から")
		println(Xml \ "element")
		println("・\\\\で階層に関わらずマッチ")
		println(Xml \\ "child")
		println("・その証拠に\\だとマッチしない")
		println(Xml \ "child")
		println("・ネームスペースは実装されていない")
		println(XmlWithNS \ "ns:element")
		println("・が、要素名だけでのマッチなら可能")
		println(XmlWithNS \ "element")
	}
}

これの結果は以下のようになります。

絶対パス指定はルート要素を省いてしまう

・つまり絶対パス指定は2段階目から
element1element2
				child1
			
・\\で階層に関わらずマッチ
child1
・その証拠に\だとマッチしない

・ネームスペースは実装されていない

・が、要素名だけでのマッチなら可能
element1element2
				child1
			


つまり、要点は

  • ルートの要素名は無視され、1階層目からマッチングが始まる
  • \\の指定で、階層に限らず要素名のマッチングが可能
  • 名前空間はサポートされていない(っぽい)が、要素名についてのマッチングは可能