tags:

views:

870

answers:

3

If you have something like:

val myStuff = Array(Person("joe",40), Person("mary", 35))

How do you create an XML value with that data as nodes? I know how to use { braces } in an XML expression to put a value, but this is a collection of values. Do I need to iterate explicitly or is there something better?

val myXml = <people>{ /* what here?! */ }</people>

The resulting value should be something like:

<people><person><name>joe</name><age>40</age></person>
<person><name>mary</name><age>39</age></person></people>
+10  A: 

As it's a functional programming language Array.map is probably what you're looking for:

class Person(name : String, age : Int){
    def toXml() = <person><name>{ name }</name><age>{ age }</age></person>;
}

object xml {
    val people = List(
     new Person("Alice", 16),
     new Person("Bob", 64)
    );

    val data = <people>{ people.map(p => p.toXml()) }</people>;

    def main(args : Array[String]){
     println(data);
    }
}

Results in:

<people><person><name>Alice</name><age>16</age></person><person><name>Bob</name><age>64</age></person></people>
Aaron Maenpaa
+2  A: 

For completeness, you can also use for..yield (or function calls):

import scala.xml

class Person(val name: String, val age: Int) {
  def toXml(): xml.Elem =
    <person><name>{ name }</name><age>{ age }</age></person>
}

def peopleToXml(people: Array[Person]): xml.Elem = {
  <people>{
    for {person <- people}
      yield person.toXml
  }</people>
}

val data = Array(new Person("joe",40), new Person("mary", 35))
println(peopleToXml(data))

(fixed error noted by Woody Folsom)

hishadow
A: 

Actually, the line yield person.toXml() does not compile for me, but yield person.toXml (without the parentheses) does. The original version complains of 'overloaded method value apply' even if I change the def of 'ToXml' to explicitly return a scala.xml.Elem

I didn't get any error in the interpreter, but maybe it's because I forgot the set the return type in toXml() so that is somehow became Unit instead. Also, I've removed a erroneous semicolon in the toXml body too. :)
hishadow