0

I got a pretty basic question but don't seem to find the elegant Scala way of doing this.

I want to insert programatically generated XML tags into an existing XML structure that I read in from a file using

xml.XML.loadFile(...)

In How do I create an XML root node in Scala without a literal element name? I found this approach for creating my tags.

def textElem(name: String, text: String) =  Elem(null, name, Null, TopScope, Text(text))

Having the XML tree

<root>
  <set start="christmas">
    <data>
      <val>ABC</val>
      ...
    </data>
    <custom> 
      <entry>DEF</entry>

      <!-- APPEND HERE -->

    </custom>
  </set>
  <set start="halloween">
     ...
  </set>
 </root>

How do I select the custom section from the christmas set, append my programatically generated XML tags and save the whole XML tree back to a file?

Thanks for your Help!

Community
  • 1
  • 1
Simon Lischka
  • 155
  • 12

1 Answers1

0

Q. How do I select the custom section from the christmas set ?
A. In Scala, we can use def \\(that: String): NodeSeq

val custom = christmas \\ "custom"
println("-- print custom element --")
println(custom)
println("-- end --")

output:

-- print custom element --
<custom> 
  <entry>DEF</entry>
  <!-- APPEND HERE -->
</custom>
-- end --

Q. append my programatically generated XML tags
A. It would be useful => scala - XML insert/update
And this link => substituting xml values programatically with scala

For example, I wrote like this:
It looks like, transform method will make it easy to manipulate XMLs.

        // Q. Append my programatically generated XML tags
        // A. Use RewriteRule#transform
        val rule = new AppendRule
        val appended = rule.transform(christmas)
        println("-- print custom element --")
        println(pp.format(appended(0)))
        println("-- end --")
    }
}

class AppendRule extends RewriteRule {
    override def transform(n: Node): Seq[Node] = n match {
        case <entry>{v}</entry> 
            => println(s"Find value in tag <entry> => $v")
               <entry>ABC</entry>
               <entry>{v}</entry>
        case elem: Elem 
            => elem copy (child = elem.child flatMap (this transform))
        case other 
            => other
    }
}

output:

Find value in tag <entry> => DEF
-- print custom element --
<root>
  <set start="christmas">
    <data>
      <val>ABC</val>
    </data>
    <custom>
      <entry>ABC</entry>
      <entry>DEF</entry>
      <!-- APPEND HERE -->
    </custom>
  </set>
  <set start="halloween"> </set>
</root>
-- end --

Q. save the whole XML tree back to a file
A. Please use scala.xml.XML#save

Community
  • 1
  • 1
hiropon
  • 1,675
  • 2
  • 18
  • 41