Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to produce nicely formatted XML in Scala?

Tags:

scala

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.

like image 424
Knut Arne Vedaa Avatar asked Jul 29 '10 16:07

Knut Arne Vedaa


People also ask

How do you format XML?

To access XML formatting options, choose Tools > Options > Text Editor > XML, and then choose Formatting.

What is Scala XML?

Scala treats XML as the first-class citizen. So, instead of embedding XML documents into strings. , you can place them inline in your code like you place an int or double value. For example. scala> val xml = Hello. xml: scala.xml.Elem = Hello.

What is an XML tag?

XML tags form the foundation of XML. They define the scope of an element in XML. They can also be used to insert comments, declare settings required for parsing the environment, and to insert special instructions.

Why use XML?

General applications: XML provides a standard method to access information, making it easier for applications and devices of all kinds to use, store, transmit, and display data.


3 Answers

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.

like image 196
Moritz Avatar answered Nov 03 '22 16:11

Moritz


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
}
like image 35
gerferra Avatar answered Nov 03 '22 16:11

gerferra


Thanks for the idea of "PrettyPrinter". That helped a lot.

I found out this way to write XML elements to a file with proper indent.

val xmlData = // your xml here

// max width: 80 chars
// indent:     2 spaces
val printer = new scala.xml.PrettyPrinter(80, 2)

XML.save("yourFileName.xml", XML.loadString(printer.format(musicMarshaledXML)) , "UTF-8", true, null)

Much appreciate any feedback about the performance or any drawbacks of this implementation (using "XML.save()")

like image 4
hel Avatar answered Nov 03 '22 18:11

hel