まず補足として、Scala XML シーンはかなり悲しいものです。アンチ XMLは有望でしたが、現在はほとんど放棄されています ( Arktekk は 2.10 で動作させましたが、その開発がどれほど活発であるかはわかりません)。ただし、 Anti-XML には非常にきちんとしたジッパーの実装がありましたが、これにより、次のようなものを記述できます。
import com.codecommit.antixml._
val myDoc = <foo><a/><c x="xxx"/><a bar="baz"><b/></a></foo>.convert
def replaceA(e: Elem) = (e \\ "a").map(_.copy(name = "AAA")).unselect
def replaceXxxC(e: Elem) = (e \\ "c").filter(
_.attrs.get("x").exists(_ == "xxx")
).map(_ => <d y="xxx"/>.convert).unselect
その後:
scala> println(replaceA(myDoc))
<foo><AAA/><c x="xxx"/><AAA bar="baz"><b/></AAA></foo>
scala> println(replaceXxxC(myDoc))
<foo><a/><d y="xxx"/><a bar="baz"><b/></a></foo>
基本的な考え方は、セレクターを使用\\
して XML に移動し、 などでローカルに「変更」を加えmap
てから、 でジッパーから戻るというものunselect
です。これは、XML 変換にジッパー (またはレンズ) を使用する主な利点です。編集用に非常に命令型の構文を使用できます (ナビゲーションとローカル変更に多かれ少なかれ似ています) だけでなく、不変性のすべての利点もあります。
Scales XMLでもこの種のことができますが、かなり複雑です。