Ответ 1
Вы можете использовать scala.xml.PrettyPrinter для его форматирования. К сожалению, это не работает для больших документов, поскольку оно только форматирует в StringBuilder
и не записывается непосредственно в поток или запись.
Предположим, вы определили следующее:
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, но если вы хотите, чтобы он был редактируемым человеком в достойном текстовом редакторе, было бы предпочтительнее отформатировать его немного красивее.
Изменяя отступы в разных точках XML-литералов Scala, делая код менее привлекательным, можно генерировать вариации вышеприведенного вывода, но кажется, что это невозможно. Я понимаю, почему он форматируется таким образом, но задайтесь вопросом, есть ли способы обойти его.
Вы можете использовать scala.xml.PrettyPrinter для его форматирования. К сожалению, это не работает для больших документов, поскольку оно только форматирует в StringBuilder
и не записывается непосредственно в поток или запись.
Я не мог найти способ использования 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
}
Спасибо за идею "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, потому что они будут сохранены в XML файле.
Я имею в виду, что ваш код должен выглядеть следующим образом:
val personsXml =
<persons>
{ persons.map(_.toXml) }
</persons>
Вместо этого:
val personsXml =
<persons>
{ persons.map(_.toXml) }
</persons>
Это отлично сработало для меня.
это мода на @answer, который может писать в целевое местоположение, которое не является локальным каталогом:
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);
Адаптировано из DOMImplementationLS сериализуется в String в UTF-8 в Java и Как довольно печатать XML с 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
}