{"id":714,"date":"2010-07-17T17:34:44","date_gmt":"2010-07-17T15:34:44","guid":{"rendered":"http:\/\/www.tutego.de\/blog\/javainsel\/2010\/07\/sieben-xstream-tipps\/"},"modified":"2010-08-03T10:57:26","modified_gmt":"2010-08-03T08:57:26","slug":"sieben-xstream-tipps","status":"publish","type":"post","link":"https:\/\/www.tutego.de\/blog\/javainsel\/2010\/07\/sieben-xstream-tipps\/","title":{"rendered":"Sieben XStream Tipps"},"content":{"rendered":"<p>1. XML-Prolog schreiben<\/p>\n<p>Das kann XStream nicht, aber beim Lesen wird der XML-Prolog \u00fcberlesen. Man muss den Prolog also von Hand in den Strom schreiben:<\/p>\n<p>Writer w = new OutputStreamWriter(<br \/>\nnew BufferedOutputStream(<br \/>\nnew FileOutputStream( file ) ), &#8222;utf-8&#8220; );<br \/>\nw.write( &#8222;&lt;?xml version=\\&#8220;1.0\\&#8220; encoding=\\&#8220;utf-8\\&#8220;?&gt;\\n&#8220; );<br \/>\nxstream.toXML( value, w );<br \/>\nw.close();<\/p>\n<p>2. Statt voll qualifizierte Klassenamen kann ein anderer Name mit alias() auf dem XStream-Objekt gesetzt werden.<\/p>\n<p>xstream.alias( &#8222;Course&#8220;, Course.class );<br \/>\nxstream.alias( &#8222;Contact&#8220;, Contact.class );<\/p>\n<p>3. Statt geschachtelte Elemente sollen gewisse Dinge in Attributen stehen:<\/p>\n<p>xstream.useAttributeFor( TrainerCourse.class, &#8222;price&#8220; );<br \/>\nxstream.useAttributeFor( TrainerCourse.class, &#8222;languages&#8220; );<\/p>\n<p>4. Statt Elemente von Sammlungen in ein eigenes Container-Element zu setzen, kann das auch ohne \u00dcberelement gesetzt werden:<\/p>\n<p>xstream.addImplicitCollection( Trainer.class, &#8222;trainerCourses&#8220; );<\/p>\n<p>5. Gewisse Dinge sollen anders geschrieben werden. Konverter sind angebracht:<\/p>\n<p>xstream.registerConverter( new TrainerCourseConverter() );<br \/>\nxstream.registerConverter( new YYYYMMDDConverter() );<\/p>\n<p>Konverter k\u00f6nnen ganz eigenst\u00e4ndig entwickelt werden (1. Bsp.), oder eine Basisklasse (2. Bsp.) vereinfacht das:<\/p>\n<p>class TrainerCourseConverter implements Converter<br \/>\n{<br \/>\n@Override<br \/>\npublic void marshal( Object value, HierarchicalStreamWriter writer, MarshallingContext arg2 )<br \/>\n{<br \/>\nTrainerCourse tc = (TrainerCourse) value;<br \/>\nwriter.addAttribute( &#8222;courseCode&#8220;, c.getCourseCode() );<br \/>\n}<\/p>\n<p>@Override<br \/>\npublic Object unmarshal( HierarchicalStreamReader arg0, UnmarshallingContext arg1 )<br \/>\n{<br \/>\n\u2026<br \/>\n}<\/p>\n<p>@SuppressWarnings( &#8222;unchecked&#8220; )<br \/>\n@Override<br \/>\npublic boolean canConvert( Class clazz\u00a0 )<br \/>\n{<br \/>\nreturn clazz.equals( TrainerCourse.class );<br \/>\n}<br \/>\n}<\/p>\n<p>Zweiter einfacher Konverter:<\/p>\n<p>class YYYYMMDDConverter extends AbstractSingleValueConverter<br \/>\n{<br \/>\n@SuppressWarnings( &#8222;unchecked&#8220; )<br \/>\npublic boolean canConvert( Class clazz )<br \/>\n{<br \/>\nreturn clazz.equals( Date.class );<br \/>\n}<\/p>\n<p>@Override<br \/>\npublic Object fromString( String str )<br \/>\n{<br \/>\nreturn StringUtils2.isEmpty( str ) ? null : DateUtils.parseDDMMYYYY( str );<br \/>\n}<\/p>\n<p>@Override<br \/>\npublic String toString( Object obj )<br \/>\n{<br \/>\nreturn obj == null ? &#8222;&#8220; : DateUtils.formatDDMMYY( (Date) obj );<br \/>\n}<br \/>\n}<\/p>\n<p>6. Elemente mit bekannten Namen sollen in einer CDATA-Umgebung geschrieben werden:<\/p>\n<p>xstream = new XStream( new XppDriver() {<br \/>\npublic HierarchicalStreamWriter createWriter( Writer out ) {<br \/>\nreturn new PrettyPrintWriter( out ) {<br \/>\nboolean isCDATA = false;<br \/>\n@SuppressWarnings( &#8222;unchecked&#8220; ) @Override public void startNode( String name, Class clazz ) {<br \/>\nsuper.startNode( name, clazz );<br \/>\nisCDATA = name.equals( &#8222;contents&#8220; ) || name.equals( &#8222;description&#8220; );<br \/>\n}<br \/>\n@Override protected void writeText( QuickWriter writer, String text ) {<br \/>\nif ( isCDATA ) { writer.write( &#8222;&lt;![CDATA[\\n&#8220; ); writer.write( text ); writer.write( &#8222;\\n]]&gt;&#8220; ); }<br \/>\nelse super.writeText( writer, text );<br \/>\n}<br \/>\n};<br \/>\n}<br \/>\n} );<\/p>\n<p>7. XStream soll XML-Dateien selbst laden und speichern (<a href=\"http:\/\/xstream.codehaus.org\/persistence-tutorial.html\">http:\/\/xstream.codehaus.org\/persistence-tutorial.html<\/a>)<\/p>\n<p>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(), \u2026 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.<\/p>\n<p>PersistenceStrategy strategy = new FilePersistenceStrategy(new File(&#8222;\/tmp&#8220;));<br \/>\nMap\u00a0 map= new XmlMap( strategy );<\/p>\n<p>Die Dateinamen sind etwas merkw\u00fcrdig, etwa <a href=\"mailto:long@12345676\">long@12345676<\/a>, aber dass ist kein Wunder, denn der Dateiname kodiert den Schl\u00fcssel, denn XStream muss ja bei einem get() etwa die XML-Datei wiederfinden.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1. XML-Prolog schreiben Das kann XStream nicht, aber beim Lesen wird der XML-Prolog \u00fcberlesen. Man muss den Prolog also von Hand in den Strom schreiben: Writer w = new OutputStreamWriter( new BufferedOutputStream( new FileOutputStream( file ) ), &#8222;utf-8&#8220; ); w.write( &#8222;&lt;?xml version=\\&#8220;1.0\\&#8220; encoding=\\&#8220;utf-8\\&#8220;?&gt;\\n&#8220; ); xstream.toXML( value, w ); w.close(); 2. Statt voll qualifizierte Klassenamen kann [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","_links_to":"","_links_to_target":""},"categories":[4],"tags":[],"class_list":["post-714","post","type-post","status-publish","format-standard","hentry","category-open-source"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/714","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/comments?post=714"}],"version-history":[{"count":2,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/714\/revisions"}],"predecessor-version":[{"id":734,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/714\/revisions\/734"}],"wp:attachment":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/media?parent=714"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/categories?post=714"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/tags?post=714"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}