How can I transform only the top level nodes of an xml file in scala (not the descendants)



I have some xml where there is an <id/> node at the top level, and also inside descendant nodes. Is there a way for me to change the value at the top level and not at the lower levels?


Sample input is



val inputXml =
<top>
<id>123</id>
<a>
<id>innerId</id>
</a>
<b>other info</b>
<c>
<id>444</id>
</c>
</top>


The output I'd like to see is:



val expectedOutputXml =
<top>
<id>999</id>
<a>
<id>innerId</id>
</a>
<b>other info</b>
<c>
<id>444</id>
</c>
</top>


I've tried using RewriteRule like this:



import scala.xml.transform.{RewriteRule, RuleTransformer}
import scala.xml.{Elem, Node, NodeSeq}

def changeTopId(root:Node, newId:String) = {

val dontChg = root \ "_" filter {e => List("a", "b").contains(e.label)}

object t1 extends RewriteRule{
override def transform(n: Seq[Node]): Seq[Node] = n match {
case e:Elem if dontChg.contains(e) => e
case e:Elem if e.label == "id" => <id>{newId}</id>
case other => other
}
}
object changeTopOne extends RuleTransformer(t1)

changeTopOne(root)
}


But it affects all <id/> nodes, resulting in:



scala> changeTopId(inputXml, "999")
res1: scala.xml.Node =
<top>
<id>999</id>
<a>
<id>999</id>
</a>
<b>other info</b>
<c>
<id>999</id>
</c>
</top>


Thanks


No comments:

Post a Comment