问题
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.
回答1:
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>
回答2:
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) }
来源:https://stackoverflow.com/questions/2477382/how-do-i-create-an-xml-root-node-in-scala-without-a-literal-element-name