如何在 Scala 中生成格式良好的 XML?
Posted
技术标签:
【中文标题】如何在 Scala 中生成格式良好的 XML?【英文标题】:How to produce nicely formatted XML in Scala? 【发布时间】:2011-03-22 20:00:06 【问题描述】:假设您定义了以下内容:
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 文字各个点的缩进 - 使代码看起来 less 漂亮 - 可以生成上述输出的变体,但似乎不可能完全正确。我理解为什么它会变成这种格式,但想知道是否有任何方法可以解决它。
【问题讨论】:
【参考方案1】:您可以使用scala.xml.PrettyPrinter 对其进行格式化。遗憾的是,这不适用于大型文档,因为它只能格式化为 StringBuilder
,并且不能直接写入流或写入器。
【讨论】:
【参考方案2】:我找不到使用 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
【讨论】:
【参考方案3】:感谢“PrettyPrinter”的创意。这帮助很大。
我发现了这种将 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)
非常感谢任何有关此实现的性能或任何缺点的反馈(使用“XML.save()”)
【讨论】:
这很好用。我使用 XML.write 对这种方法进行了改动,因此我可以指定目标目录。【参考方案4】:也许会有用。 使用文本编辑器时,尽量不要在 XML 代码中放置任何额外的选项卡,因为它们将保存在 xml 文件中。
我的意思是,你的代码应该是这样的:
val personsXml =
<persons>
persons.map(_.toXml)
</persons>
而不是这个:
val personsXml =
<persons>
persons.map(_.toXml)
</persons>
它非常适合我。
【讨论】:
【参考方案5】:这是@Hel's 答案的模组,可以写入非本地目录的目标位置:
val printer = new PrettyPrinter(80, 2)
val targetFile = new java.io.File("./mytargetdir/file.xml")
val prettyDoc = printer.format(document)
val writer = new java.io.FileWriter(targetFile)
scala.xml.XML.write(writer, XML.loadString(prettyDoc), "UTF-8", true, null)
org.apache.commons.io.IOUtils.closeQuietly(writer);
【讨论】:
【参考方案6】:改编自DOMImplementationLS serialize to String in UTF-8 in Java和How 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
【讨论】:
以上是关于如何在 Scala 中生成格式良好的 XML?的主要内容,如果未能解决你的问题,请参考以下文章