How do I create an XML root node in Scala without a literal element name?
Asked Answered
T

2

7

I'm looking to create a document like this:

<root/>

That I can add children to programatically. Theoretically, it would look like this:

val root_node_name = "root"
val doc = <{root_node_name}/>

But that doesn't seem to work:

error: not found: value <

So, what I tried instead was this:

val root_node_name = "root"
val doc = new scala.xml.Elem(null, root_node_name, null, scala.xml.TopScope, null)  

That compiles but at runtime I get this null pointer exception:

java.lang.NullPointerException
at scala.xml.Utility$.toXML(Utility.scala:201)
at scala.xml.Utility$$anonfun$sequenceToXML$2.apply(Utility.scala:235)
at scala.xml.Utility$$anonfun$sequenceToXML$2.apply(Utility.scala:235)
at scala.Iterator$class.foreach(Iterator.scala:414)
at scala.runtime.BoxedArray$AnyIterator.foreach(BoxedArray.scala:45)
at scala.Iterable$class.foreach(Iterable...

I'm using Scala 2.8. Any examples of how to pull this off? Thanks.

Tarter answered 19/3, 2010 at 12:54 Comment(0)
I
7

You should pass the empty list for attributes (scala.xml.Null) and if you don't want any children, you shouldn't even include the final argument. You want an empty list of children, not a single child that happens to be null. So:

scala> val root_node_name = "root"
root_node_name: java.lang.String = root

scala> val doc = new scala.xml.Elem(null, root_node_name, scala.xml.Null , scala.xml.TopScope)
doc: scala.xml.Elem = <root></root>
Interrogatory answered 19/3, 2010 at 14:54 Comment(2)
This runs with deprecation warning now.Nadinenadir
With the current API (Scala.xml 2.11.x): val doc = Elem.apply(null, root_node_name, scala.xml.Null, scala.xml.TopScope)Bradlybradman
V
5

On 2.8 you can do this:

scala> val r = <root/>
r: scala.xml.Elem = <root></root>

scala> r.copy(label="bar")
res0: scala.xml.Elem = <bar></bar>

So if your initial document is <root/>, then just use a literal. If you need to be able to set the label at runtime, you can define a method like this:

def newRoot(label:String) = {val r = <root/>; r.copy(label=label) }
Villeneuve answered 19/3, 2010 at 17:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.