2009-11-18 6 views
6

Dieser Code:Wie kann ich XStream bekommen, um Scala-Listen schön auszugeben? Kann ich einen benutzerdefinierten Konverter schreiben?

println(new XStream.toXML(List(1,2,3))) 

produziert diese XML:

<scala.coloncolon serialization="custom"> 
    <unserializable-parents/> 
    <scala.coloncolon> 
    <int>1</int> 
    <int>2</int> 
    <int>3</int> 
    <scala.ListSerializeEnd/> 
    </scala.coloncolon> 
</scala.coloncolon> 

Stattdessen würde ich dies mag:

<list> 
    <int>1</int> 
    <int>2</int> 
    <int>3</int> 
</list> 

, die ähnlich sein würde, wie die generische Java-Sammlungen serialisiert bekommen. Was ist der beste Weg, dies zu tun?

Ich habe die meisten der Weg dorthin bekam von meinem eigenen Konverter Umsetzung, aber ich bin fest auf der Abstellungsmethode, es ist nicht klar, wie eine leere Liste instanziiert ...

class ListConverter(_mapper : Mapper) extends AbstractCollectionConverter(_mapper) { 
    /** Helper method to use x.getClass 
    * 
    * See: http://scalide.blogspot.com/2009/06/getanyclass-tip.html 
    */ 
    def getAnyClass(x: Any) = x.asInstanceOf[AnyRef].getClass 

    def canConvert(clazz: Class[_]) = {  
    classOf[::[_]] == clazz 
    } 

    def marshal(value: Any, writer: HierarchicalStreamWriter, context: MarshallingContext) = { 
    val list = value.asInstanceOf[List[_]] 
    for (item <- list) {  
     writeItem(item, context, writer) 
    } 
    } 

    def unmarshal(reader: HierarchicalStreamReader, context: UnmarshallingContext) = { 
    println(context.getRequiredType()) 
    var list : List[_] = createCollection(context.getRequiredType()).asInstanceOf[List[_]] 
    while (reader.hasMoreChildren()) { 
     reader.moveDown(); 
     val item = readItem(reader, context, list); 
     list = item :: list 
     reader.moveUp(); 
    } 
    list 
    } 
} 

object ListConverter { 
    def configureXStream(stream: XStream) = { 
    stream.alias("list", classOf[::[_]]) 
    stream.registerConverter(new ListConverter(stream.getMapper))   
    } 
} 

Antwort

2

Nicht Sekunden nachdem die Frage der Veröffentlichung, kam die Antwort auf mich, hier ist eine funktionierende Implementierung von Abstellungs:

def unmarshal(reader: HierarchicalStreamReader, context: UnmarshallingContext) = { 
    var list : List[_] = Nil 
    while (reader.hasMoreChildren()) { 
     reader.moveDown(); 
     val item = readItem(reader, context, list); 
     list = list ::: List(item) // be sure to build the list in the same order 
     reader.moveUp(); 
    } 
    list 
    } 
1

Es gibt nur eine Instanz einer leeren Liste, die das Objekt Nil ist.

+0

Könnten Sie näher ausführen? Ich sehe nicht die Relevanz Ihrer Antwort auf die Frage –

+0

Sie fragte, wie Sie eine leere Liste instanziieren können. Ich sage nur, dass es nur eine leere Liste gibt, die "Nil" ist. Sie müssen sich also darauf beziehen - wie Sie es in dem Code getan haben, den Sie in Ihrer Antwort gezeigt haben. –

+0

Macht vollkommen Sinn jetzt, dass Sie es erklären, thx! –