如何在Scala中生成格式良好的XML?

时间:2010-07-29 16:09:40

标签: scala

假设您定义以下内容:

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))

然后生成一些XML并将其保存到文件中:

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

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

你最终会得到以下有趣的文字:

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

现在,当然,这是完全有效的XML,但是如果你想让它在一个体面的文本编辑器中是人类可编辑的,那么将更好来使它格式化得更好一些。

通过更改Scala XML文字的各个点上的缩进 - 使代码看起来更少更好 - 可以生成上述输出的变体,但似乎不可能完全正确。我理解为什么它会以这种方式格式化,但想知道是否有任何方法可以解决它。

5 个答案:

答案 0 :(得分:21)

您可以使用scala.xml.PrettyPrinter对其进行格式化。遗憾的是,这不适用于大型文档,因为它只能格式化为StringBuilder并且不会直接写入流或写入器。

答案 1 :(得分:14)

我找不到使用PrettyPrinter的方法,也直接指定文件编码。我找到的“解决方案”是:

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
}

答案 2 :(得分:2)

感谢&#34; PrettyPrinter&#34;的想法。这有很大帮助。

我发现这种方法可以将XML元素写入具有适当缩进的文件。

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)

非常感谢有关此实现的性能或任何缺点的任何反馈(使用&#34; XML.save()&#34;)

答案 3 :(得分:1)

也许它会有用。 当您使用文本编辑器时,请尝试不要在XML代码中添加任何额外的选项卡,因为它们将保存在xml文件中。

我的意思是,您的代码应如下所示:

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

而不是:

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

这对我来说非常有用。

答案 4 :(得分:0)

改编自DOMImplementationLS serialize to String in UTF-8 in JavaHow to pretty print XML from Java?

  def cleanXml(xml: String): String = {
    import org.w3c.dom.Node
    import org.w3c.dom.bootstrap.DOMImplementationRegistry
    import org.w3c.dom.ls.DOMImplementationLS
    import org.w3c.dom.ls.LSSerializer
    import org.xml.sax.InputSource
    import javax.xml.parsers.DocumentBuilderFactory
    import java.io.StringReader
    val src = new InputSource(new StringReader(xml))
    val document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(src).getDocumentElement
    val keepDeclaration = java.lang.Boolean.valueOf(xml.startsWith("<?xml"))
    val registry = DOMImplementationRegistry.newInstance()
    val impl = registry.getDOMImplementation("LS").asInstanceOf[DOMImplementationLS]
    val lsOutput = impl.createLSOutput
    lsOutput.setEncoding("UTF-8")
    import java.io.StringWriter
    val stringWriter = new StringWriter
    lsOutput.setCharacterStream(stringWriter)
    val writer = impl.createLSSerializer()
    writer.getDomConfig.setParameter("format-pretty-print", true)
    writer.getDomConfig.setParameter("xml-declaration", keepDeclaration)
    writer.write(document, lsOutput)
    stringWriter.toString
  }