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のパーズと組み合わせるとなかなか威力を発揮するようだ。