ScalaでXMLをパーズする

ネット上にはなんていうか「試しにやってみました」程度の簡単な例しか転がっていないので多少複雑な例を。以下のようなXML(sample-1.xmlとする)があったとして

<?xml version="1.0" encoding="utf-8" ?>
<ninjas>
  <ninja id="ninjaslayer">
    <attacks>
      <attack name="Suriken">
        <damage>10</damage>
        <times>1000</times>
      </attack>
      <attack name="Meia lua de compasso">
        <damage>50</damage>
        <times>30</times>
      </attack>
      <attack name="Tsuyoi suriken">
        <damage>100</damage>
        <times>2</times>
      </attack>
      <attack name="Evil Black Fire">
        <damage>500</damage>
        <times>1</times>
        <condition>Controlled by Naraku</condition>
        <condition>Unconsious</condition>
      </attack>
      <attack name="Sacred Nunchaku">
        <damage>1000</damage>
        <times>1</times>
        <condition>Synchronized with Naraku</condition>
        <condition>Clutch Situation</condition>
      </attack>
    </attacks>
    <name>Ninja Slayer</name>
  </ninja>
  <ninja id="forest-sawatari">
    <attacks>
      <attack name="Machete">
        <damage>50</damage>
        <times>10</times>
      </attack>
      <attack name="Bio takeyari">
        <damage>50</damage>
        <times>10</times>
      </attack>
    </attacks>
    <name>Forest Sawatari</name>
  </ninja>
  <ninja id="frogman">
    <attacks>
      <attack name="Bio Frogs Tongue">
        <damage>50</damage>
        <times>100</times>
      </attack>
      <attack name="Makimono Jitsu">
        <damage>300</damage>
        <times>30</times>
      </attack>
    </attacks>
    <name>Frogman</name>
  </ninja>
  <ninja id="frogman">
    <attacks>
      <attack name="Bio Frogs Tongue">
        <damage>50</damage>
        <times>100</times>
      </attack>
      <attack name="Makimono Jitsu">
        <damage>300</damage>
        <times>30</times>
      </attack>
    </attacks>
    <name>Frogman</name>
  </ninja>
  <ninja id="genocide">
    <attacks>
      <attack name="Buzzsaw">
        <damage>500</damage>
        <times>100</times>
      </attack>
    </attacks>
    <name>Genocide</name>
  </ninja>
  <ninja id="evolver">
    <attacks>
      <attack name="Ochoko Defence">
        <damage>1</damage>
        <times>100</times>
      </attack>
      <attack name="Ju Jitsu">
        <damage>50</damage>
        <times>100</times>
      </attack>
      <attack name="Evolution">
        <damage>150</damage>
        <times>100</times>
      </attack>
      <attack name="Supersize">
        <damage>150</damage>
        <times>10</times>
      </attack>
      <attack name="Monsterize">
        <damage>750</damage>
        <times>1</times>
        <condition> Supersized </condition>
      </attack>
    </attacks>
    <name>Evolver</name>
  </ninja>
</ninjas>

ニンジャ名の一覧をStringのリストで取りたい。どうするか。

import scala.xml._
val xm = XML.loadFile("sample-1.xml")

で、変数xmにXMLとして取り込んだとする。
単純に

xm \\ "name"

とすると結果は

NodeSeq(<name>Ninja Slayer</name>, <name>Forest Sawatari</name>, <name>Frogman</name>, <name>Frogman</name>, <name>Genocide</name>, <name>Evolver</name>)

となるので

for(x <- xm \\ "name" ) yield x.text 

としてあげるとこの式の値が

scala.collection.immutable.Seq[String] = List(Ninja Slayer, Forest Sawatari, Frogman, Frogman, Genocide, Evolver)

となり目的達成。
Scalaのfor文は強力なのでこのようにXMLのパーズと組み合わせるとなかなか威力を発揮するようだ。