---
title: 'Sieben XStream Tipps'
url: 'https://tutego.de/blog/javainsel/2010/07/sieben-xstream-tipps'
markdown: 'https://tutego.de/blog/javainsel/2010/07/sieben-xstream-tipps.md'
date: '2010-07-17'
description: '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\\" encod…'
taxonomy:
  category:
    - 'Open Source'
---

# Sieben XStream Tipps

![Illustration einer tropischen Insel mit Palmen und einem hohen Berg](https://tutego.de/blog/javainsel/user/themes/tutego/images/insel-cover.jpg)# Java Blog für Programmierer

[Java Blog für Programmierer](https://tutego.de/blog/javainsel/)

## Sieben XStream Tipps

17.07.2010 · [Christian Ullenboom](https://tutego.de/blog/javainsel/author/admin/)

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:

```java
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.

```java
xstream.alias( "Course", Course.class );
xstream.alias( "Contact", Contact.class );
```

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

```java
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:

```java
xstream.addImplicitCollection( Trainer.class, "trainerCourses" );
```

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

```java
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:

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

```java
{
```

…

```
}

@SuppressWarnings( "unchecked" )
@Override
```

public boolean `canConvert( Class clazz )`

```java
{
return clazz.equals( TrainerCourse.class );
}
}
```

Zweiter einfacher Konverter:

```java
class YYYYMMDDConverter extends AbstractSingleValueConverter
{
@SuppressWarnings( "unchecked" )
```

public boolean `canConvert( Class clazz )`

```java
{
return clazz.equals( Date.class );
}

@Override
```

public `Object` `fromString( String str )`

```java
{
return StringUtils2.isEmpty( str ) ? null : DateUtils.parseDDMMYYYY( str );
}

@Override
```

public `String` `toString( Object obj )`

```java
{
return obj == null ? "" : DateUtils.formatDDMMYY( (Date) obj );
}
}
```

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

```java
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 ()

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.

```java
PersistenceStrategy strategy = new FilePersistenceStrategy(new File("/tmp"));
Map map= new XmlMap( strategy );
```

Die Dateinamen sind etwas merkwürdig, etwa [long@12345676](mailto: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.

Kategorien: [Open Source](https://tutego.de/blog/javainsel/category/open-source/)

[← Alle Beiträge](https://tutego.de/blog/javainsel/)

---

## Navigation

- Previous: [Neue Spezifikation von ARM-Blöcken in Java 7](https://tutego.de/blog/javainsel/2010/07/neue-spezifikation-von-arm-blcken-in-java-7.md)
- Next: [Erinnerung: iText ist Affero GPL Lizenz](https://tutego.de/blog/javainsel/2010/07/erinnerung-itext-ist-affero-gpl-lizenz.md)
