Modifying xml contents scala

93 Views Asked by At

I have a problem similar to Scala - modifying nested elements in xml I have reproduced the same code in this post. I am trying to modify content in an element and I have to call a function to get the content. For eg.

object test extends App {
  val InputXml: Node =
    <root>
      <contents>
        <version>1</version>
      </contents>
    </root>

  object t1 extends RewriteRule {
    override def transform(n: Node): Seq[Node] = {
      println("transforming '" + n + "'")
      n match {
        case Elem(prefix, "version", attribs, scope, _*) =>
          Elem(prefix, "version", attribs, scope, true, Text(computeVersion()))

        case other => other
      }
    }

    def computeVersion() = {
      println("computeVersion called")
      "3.0"
    }
  }

  object rt1 extends RuleTransformer(t1)
  val res = rt1(InputXml)
  val pp = new PrettyPrinter(width = 2, step = 1)
  Console println (pp format res)
}

Output is :

transforming ' '
transforming '1'
transforming '<version>1</version>'
computeVersion called
transforming '<version>1</version>'
computeVersion called
transforming '1'
transforming '<version>1</version>'
computeVersion called
transforming '<version>1</version>'
computeVersion called
transforming '<contents> <version>3.0</version></contents>'
transforming ' '
transforming '1'
transforming '<version>1</version>'
computeVersion called
transforming '<version>1</version>'
computeVersion called
transforming '1'
transforming '<version>1</version>'
computeVersion called
transforming '<version>1</version>'
computeVersion called
transforming '<contents> <version>3.0</version></contents>'
transforming '<root><contents> <version>3.0</version></contents></root>'
<root><contents> <version>3.0</version></contents></root>

computeVersion() is getting called almost every time due to complexity. I would just want it to be called when the actual tag is being processed. I tried to surround it by pattern matches like searching for <version> which is really not working out.
Any suggestions ?

1

There are 1 best solutions below

0
On

I got this fixed. This issue is addressed in https://github.com/scala/scala-xml/issues/58

Although the fix is available in 2.12-M3 (as of today) version of scala, folks like me who use 2.11 version of scala can override the transform method in the class and paste the code which is

 def transform(ns: Seq[Node]): Seq[Node] = {
    val changed = ns flatMap transform
    if (changed.length != ns.length || (changed, ns).zipped.exists(_ != _)) changed
else ns
}