Sieben XStream Tipps

1. XML-Prolog schreiben

Das kann XStream nicht, aber beim Lesen wird der XML-Prolog überlesen. Man muss den Prolog also von Hand in den Strom schreiben:

Writer w = new OutputStreamWriter(
new BufferedOutputStream(
new FileOutputStream( file ) ), „utf-8“ );
w.write( „<?xml version=\“1.0\“ encoding=\“utf-8\“?>\n“ );
xstream.toXML( value, w );
w.close();

2. Statt voll qualifizierte Klassenamen kann ein anderer Name mit alias() auf dem XStream-Objekt gesetzt werden.

xstream.alias( „Course“, Course.class );
xstream.alias( „Contact“, Contact.class );

3. Statt geschachtelte Elemente sollen gewisse Dinge in Attributen stehen:

xstream.useAttributeFor( TrainerCourse.class, „price“ );
xstream.useAttributeFor( TrainerCourse.class, „languages“ );

4. Statt Elemente von Sammlungen in ein eigenes Container-Element zu setzen, kann das auch ohne Überelement gesetzt werden:

xstream.addImplicitCollection( Trainer.class, „trainerCourses“ );

5. Gewisse Dinge sollen anders geschrieben werden. Konverter sind angebracht:

xstream.registerConverter( new TrainerCourseConverter() );
xstream.registerConverter( new YYYYMMDDConverter() );

Konverter können ganz eigenständig entwickelt werden (1. Bsp.), oder eine Basisklasse (2. Bsp.) vereinfacht das:

class TrainerCourseConverter implements Converter
{
@Override
public void marshal( Object value, HierarchicalStreamWriter writer, MarshallingContext arg2 )
{
TrainerCourse tc = (TrainerCourse) value;
writer.addAttribute( „courseCode“, c.getCourseCode() );
}

@Override
public Object unmarshal( HierarchicalStreamReader arg0, UnmarshallingContext arg1 )
{

}

@SuppressWarnings( „unchecked“ )
@Override
public boolean canConvert( Class clazz  )
{
return clazz.equals( TrainerCourse.class );
}
}

Zweiter einfacher Konverter:

class YYYYMMDDConverter extends AbstractSingleValueConverter
{
@SuppressWarnings( „unchecked“ )
public boolean canConvert( Class clazz )
{
return clazz.equals( Date.class );
}

@Override
public Object fromString( String str )
{
return StringUtils2.isEmpty( str ) ? null : DateUtils.parseDDMMYYYY( str );
}

@Override
public String toString( Object obj )
{
return obj == null ? „“ : DateUtils.formatDDMMYY( (Date) obj );
}
}

6. Elemente mit bekannten Namen sollen in einer CDATA-Umgebung geschrieben werden:

xstream = new XStream( new XppDriver() {
public HierarchicalStreamWriter createWriter( Writer out ) {
return new PrettyPrintWriter( out ) {
boolean isCDATA = false;
@SuppressWarnings( „unchecked“ ) @Override public void startNode( String name, Class clazz ) {
super.startNode( name, clazz );
isCDATA = name.equals( „contents“ ) || name.equals( „description“ );
}
@Override protected void writeText( QuickWriter writer, String text ) {
if ( isCDATA ) { writer.write( „<![CDATA[\n“ ); writer.write( text ); writer.write( „\n]]>“ ); }
else super.writeText( writer, text );
}
};
}
} );

7. XStream soll XML-Dateien selbst laden und speichern (http://xstream.codehaus.org/persistence-tutorial.html)

Verwaltet man viele kleine XML-Dokumenten, etwa Kontakte, kann XStream diese XML-Kontakt-Dateien automatisch anlegen, lesen und aktualisieren. Der Tick ist, dass man alle Daten in eine spezielle Map, Set oder List setzt. Die XStream-Implementierungen der add(), put(), get(), … Methoden sind so realisiert, dass die Daten beim add()/put() in die Datenstruktur und gleichzeitig XML-serialisiert als Datei ins Dateisystem kommen. In welches Verzeichnis sagt die FilePersistenceStrategy.

PersistenceStrategy strategy = new FilePersistenceStrategy(new File(„/tmp“));
Map  map= new XmlMap( strategy );

Die Dateinamen sind etwas merkwürdig, etwa long@12345676, aber dass ist kein Wunder, denn der Dateiname kodiert den Schlüssel, denn XStream muss ja bei einem get() etwa die XML-Datei wiederfinden.

Ähnliche Beiträge

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert