tags:

views:

94

answers:

2

Say you define the following:

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

val Persons = List(new Person("John", 34), new Person("Bob", 45))

Then generate some XML and save it to a file:

val personsXml = 
    <persons>
        { persons.map(_.toXml) }
    </persons>

scala.xml.XML.save("persons.xml", personsXml)

You end up with the following funny-looking text:

<persons>
        <person>
            <name>John</name>
            <age>32</age>
        </person><person>
            <name>Bob</name>
            <age>43</age>
        </person>
    </persons>

Now, of course, this is perfectly valid XML, but if you want it to be human-editable in a decent text editor, it would be preferable to have it formatted a little more nicely.

By changing indentation on various points of the Scala XML literals - making the code look less nice - it's possible to generate variations of the above output, but it seems impossible to get it quite right. I understand why it becomes formatted this way, but wonder if there are any ways to work around it.

+5  A: 

You can use scala.xml.PrettyPrinter to format it. Sadly this does not work for large documents as it only formats into a StringBuilder and does not write directly into a stream or writer.

Moritz
That worked great. Thanks.
Knut Arne Vedaa
+1  A: 

I could not find a way to use the PrettyPrinter and also specify the file encoding directly. The "solution" that I found was this:

val Encoding = "UTF-8"

def save(node: Node, fileName: String) = {

    val pp = new PrettyPrinter(80, 2)
    val fos = new FileOutputStream(fileName)
    val writer = Channels.newWriter(fos.getChannel(), Encoding)

    try {
        writer.write("<?xml version='1.0' encoding='" + Encoding + "'?>\n")
        writer.write(pp.format(node))
    } finally {
        writer.close()
    }

    fileName
}
german1981