Scala の XML パターンマッチング
Scala のパターンマッチング機能は非常に強力で、XML もパターンマッチング対象にする事ができる。という事で簡単に試してみた。
今回、試した環境は以下の通り。
- Scala 2.7.3
XML パターン指定
XML のパターン指定は以下のように XML の要素と "{パターン}" という記述を使って行える。
- <要素名>{パターン}要素名>
{パターン} の定義方法は以下のようなものがある。
- {変数名} で 1つのノードを持つ要素にマッチ
- {変数名 @ _*} で複数のノードを持つ要素にマッチし Array や ArrayBuffer でマッチ箇所を取得
なお、今のところ属性定義は使えないみたい。(<要素名 属性名="xxx"> のようなパターン指定はできない模様)
xml_match.scala ファイル
import scala.xml.Node def check(node: Node): Unit = node match { case <data>{ d }</data> => println("1: '" + d + "'") case <data>{ d @ _* }</data> => println("2: " + d) case _ => println("3: no match") } check(<data>test1</data>) check(<data>test2<abc /> <name><no>first</no></name></data>) check(<data><a href="">http://</a></data>) check(<data />) check(<data></data>) check(<data> </data>) check(<data> </data>) check(<data name="test">123</data>) check(<dataList>a</dataList>)
実行結果
>scala xml_match.scala 1: 'test1' 2: ArrayBuffer(test2, <abc></abc>, , <name><no>first</no></name>) 1: '<a href="">http://</a>' 2: Array() 2: Array() 1: ' ' 1: ' ' 1: '123' 3: no match
上記の結果より、スペースや改行もマッチしており、 や は { d @ _* } の方にマッチしている事がわかる。
Elem シングルトンオブジェクトを使ったパターン指定
XML の要素を使ってパターン指定する代わりに Elem シングルトンオブジェクトを使う方法も用意されている。
Elem の場合は以下のような記述を使う事になる。
- Elem(接頭子, 要素名, 属性, スコープ, パターン)
"<要素名>{パターン}要素名>" という XML パターンを Elem で置き換えると以下のようになる
- Elem(_, 要素名, _, _, パターン)
xml_match.scala ファイルの XML パターン部分を Elem を使って書き換えたのが以下。
xml_match2.scala ファイル
import scala.xml.{Node, Elem} def check(node: Node): Unit = node match { case Elem(_, "data", _, _, d) => println("1: '" + d + "'") case Elem(_, "data", _, _, d @ _ *) => println("2: " + d) case _ => println("3: no match") } check(<data>test1</data>) check(<data>test2<abc /> <name><no>first</no></name></data>) check(<data><a href="">http://</a></data>) check(<data />) check(<data></data>) check(<data> </data>) check(<data> </data>) check(<data name="test">123</data>) check(<dataList>a</dataList>)
実行結果
>scala xml_match2.scala 1: 'test1' 2: ArrayBuffer(test2, <abc></abc>, , <name><no>first</no></name>) 1: '<a href="">http://</a>' 2: Array() 2: Array() 1: ' ' 1: ' ' 1: '123' 3: no match
実行結果は XML パターンを使った場合と同じになる。