24 Stimmen

Wie erzeugt man schön formatiertes XML in Scala?

Nehmen wir an, Sie definieren das Folgende:

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

Erstellen Sie dann eine XML-Datei und speichern Sie sie in einer Datei:

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

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

Sie erhalten den folgenden lustig aussehenden Text:

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

Dies ist natürlich vollkommen gültiges XML, aber wenn Sie wollen, dass es in einem anständigen Texteditor von Menschen bearbeitet werden kann, wäre es vorzugsweise um sie ein wenig besser zu formatieren.

Durch das Ändern der Einrückung an verschiedenen Stellen der Scala-XML-Literale - so dass der Code aussieht weniger schön - es ist möglich, Variationen der obigen Ausgabe zu erzeugen, aber es scheint unmöglich zu sein, es ganz richtig hinzubekommen. Ich verstehe warum es wird auf diese Weise formatiert, aber ich frage mich, ob es irgendwelche Möglichkeiten gibt, das zu umgehen.

22voto

Moritz Punkte 14044

Sie können verwenden scala.xml.PrettyPrinter um es zu formatieren. Leider funktioniert dies nicht für große Dokumente, da es nur in eine StringBuilder und schreibt nicht direkt in einen Stream oder Writer.

15voto

gerferra Punkte 1489

Ich konnte keine Möglichkeit finden, den PrettyPrinter zu verwenden und auch die Dateikodierung direkt anzugeben. Die "Lösung", die ich gefunden habe, war diese:

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
}

4voto

hel Punkte 363

Danke für die Idee mit "PrettyPrinter". Das hat sehr geholfen.

Ich habe diesen Weg gefunden, um XML-Elemente mit korrektem Einzug in eine Datei zu schreiben.

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)

Ich freue mich über jede Rückmeldung zur Leistung oder zu eventuellen Nachteilen dieser Implementierung (mit "XML.save()").

1voto

Kersh Punkte 301

Vielleicht wird es nützlich sein. Wenn Sie einen Texteditor verwenden, versuchen Sie, keine zusätzlichen Tabs in den XML-Code einzufügen, da diese in der XML-Datei gespeichert werden.

Ich meine, Ihr Code sollte so aussehen:

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

Stattdessen:

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

Bei mir hat es perfekt funktioniert.

1voto

Andrew Norman Punkte 763

Dies ist ein Mod für @Hel's Antwort, die in ein Zielverzeichnis schreiben kann, das nicht das lokale Verzeichnis ist:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X