I\'m writing a tool to update some xml files (pom.xml in this case) with scala because the effort it would take in java is significantly higher than (in theory) it is with s
You really should take a look at other questions on Stack Overflow about modifying XML. Look at the "Related" links to the right.
Here:
scala> <dependency>
| <groupId>foo</groupId>
| <artifactId>bar</artifactId>
| <version>1.0-SNAPSHOT</version>
| </dependency>
res0: scala.xml.Elem =
<dependency>
<groupId>foo</groupId>
<artifactId>bar</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
scala> new scala.xml.transform.RewriteRule {
| override def transform(n: Node): Seq[Node] = n match {
| case <version>{v}</version> if v.text contains "SNAPSHOT" => <version>{v.text.split("-")(0)}</version>
| case elem: Elem => elem copy (child = elem.child flatMap (this transform))
| case other => other
| }
| } transform res0
res9: Seq[scala.xml.Node] =
<dependency>
<groupId>foo</groupId>
<artifactId>bar</artifactId>
<version>1.0</version>
</dependency>
Text is represented as a Node
inside of the Element
s Node. So a bit of functional recursion will let you do a deep copy & filter:
def deepCopy(node:Node) : Node = node match {
case e : Elem => e.copy(child = this.child.toSeq.map(deepCopy))
case t : Text => new Text(t.text.split("-").head)
case x => x
}
disclaimer: this code was not tested for errors
Using Scalate's Scuery CSS3 transforms and scala.xml.Elem#copy
:
val xml =
<dependency>
<version>1.0-SNAPSHOT</version>
<version>2.0</version>
</dependency>
new Transformer {
$("dependency > version") { node =>
node.asInstanceOf[Elem].copy(child = Text(node.text.stripSuffix("-SNAPSHOT")))
}
}.apply(xml)
yields
NodeSeq(<dependency><version>1.0</version><version>2.0</version></dependency>)