Problem: You want to write XML data to a file in a Scala application, such as saving application data or configuration information to a file.
Solution
Use the scala.xml.XML.save
method to write a Scala literal to a file. Given this XML literal:
// create an XML variable val portfolio = <portfolio> <stocks> <stock>AAPL</stock> <stock>AMZN</stock> <stock>GOOG</stock> </stocks> <reits> <reit>Super REIT 1</reit> </reits> </portfolio>
write the literal to file with the save
method:
// save the XML to a file scala.xml.XML.save("portfolio.xml", portfolio)
This creates a plain-text file named portfolio.xml in the current directory, containing the XML literal shown.
As with any file-writing code, beware that XML.save
can throw an exception:
scala> scala.xml.XML.save("/foo/bar/baz", portfolio) java.io.FileNotFoundException: /foo/bar/baz (No such file or directory)
Additional save parameters
The save
method lets you specify other parameters, including the encoding to use, whether or not to write an XML declaration, and whether or not to write a DOCTYPE declaration.
To write the data to a file with encoding information, use this approach:
XML.save("portfolio.xml", portfolio, "UTF-8", true, null)
This results in the following header being added to the file:
<?xml version='1.0' encoding='UTF-8'?>
To add a DOCTYPE to the file, first import the necessary classes:
import scala.xml.dtd.{DocType, PublicID}
Then create a DocType
instance, and save the file with that instance:
val doctype = DocType("html", PublicID("-//W3C//DTD XHTML 1.0 Strict//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"), Nil) XML.save("portfolio.xml", portfolio, "UTF-8", true, doctype)
With this configuration, the following DOCTYPE line is added to the output file:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
The scala.xml package also includes a Utility
object with a small collection of useful methods that let you sort node attributes, trim elements, remove comments, and more.
Pretty printing
If it’s important that the XML can be easily read by a human being, it’s best to use the PrettyPrinter class to make sure the XML is “human readable.” But because the PrettyPrinter
returns a String
, you’ll need to write it to a file using another method. I have my own FileUtils
class, so the process looks like this:
val portfolio = <portfolio> <stocks> <stock>AAPL</stock><stock>AMZN</stock><stock>GOOG</stock> </stocks> <reits><reit>Super REIT 1</reit></reits> </portfolio> // 80 characters wide, 2 character indentation val prettyPrinter = new scala.xml.PrettyPrinter(80, 2) val prettyXml = prettyPrinter.format(portfolio) FileUtils.save("portfolio.xml", prettyXml)
See Also
- My Java file utilities are at http://alvinalexander.com/java/java-file-utilities, and my Scala file utilities are at https://github.com/alvinj/FileUtils