I have an object that needs to be serialised as XML, which contains the following field:
List<String> tags = new List<String>();
XStream serialises it just fine (after some aliases) like this:
<tags>
<string>tagOne</string>
<string>tagTwo</string>
<string>tagThree</string>
<string>tagFour</string>
</tags>
That's OK as far as it goes, but I'd like to be able to rename the <string>
elements to, say, <tag>
. I can't see an obvious way to do that from the alias documentation on the XStream site. Am I missing something obvious?
Out of interest I gave it a try to do it without writing my own converter. Basically I just register a special instructed version of CollectionConverter
for a certain field in a certain class.
Relevant snippet:
ClassAliasingMapper mapper = new ClassAliasingMapper(xstream.getMapper());
mapper.addClassAlias("tag", String.class);
xstream.registerLocalConverter(
Test.class,
"tags",
new CollectionConverter(mapper)
);
Full-blown example:
import com.thoughtworks.xstream.*;
import com.thoughtworks.xstream.converters.collections.*;
import com.thoughtworks.xstream.mapper.*;
import java.util.*;
public class Test {
public List<String> tags = new ArrayList<String>();
public List<String> notags = new ArrayList<String>();
public Test(String tag, String tag2) {
tags.add(tag); tags.add(tag2);
notags.add(tag); notags.add(tag2);
}
public static void main(String[] args) {
Test test = new Test("foo", "bar");
XStream xstream = new XStream();
ClassAliasingMapper mapper = new ClassAliasingMapper(xstream.getMapper());
mapper.addClassAlias("tag", String.class);
xstream.registerLocalConverter(
Test.class,
"tags",
new CollectionConverter(mapper)
);
System.out.println(xstream.toXML(test));
}
}
Not tested but this should work. No?
xstream.alias("tag", java.lang.String.class);
I'd suggest changing the List<String>
to a List<Tag>
, where Tag is a domain object that essentially just contains a String. Then you say:
xstream.alias("tag", org.goring.Tag.class);
and you get exactly what you want. This avoids having to roll your own Converter.
@XStreamAlias("example")
public class A {
private B myList;
public A(){
this.myList = new B();
}
public A clone(){
A a = new A();
a.myList = this.myList;
return a;
}
public B getMyList() {
return myList;
}
public void setMyList(B myList) {
this.myList = myList;
}
}
public class B {
@XStreamImplicit(itemFieldName = "myField")
ArrayList<String> myFieldlist;
public B(){
this.myFieldlist = new ArrayList<String>();
}
public B clone(){
B b = new B();
b.myFieldlist = this.myFieldlist;
return b;
}
public ArrayList<String> getMyFieldlist() {
return myFieldlist;
}
public void setMyFieldlist(ArrayList<String> myFieldlist) {
this.myFieldlist = myFieldlist;
}
}
public class Test {
public static void main(String[] args) {
A a = new A();
a.getMyList().getMyFieldlist().add("aa");
a.getMyList().getMyFieldlist().add("bb");
XStream xs = new XStream(new DomDriver());
xs.processAnnotations(A.class);
xs.processAnnotations(B.class);
System.out.println(xs.toXML(a));
}
}
xml result:
<example>
<myList>
<myField>aa</myField>
<myField>bb</myField>
</myList>
</example>
Add alias for the java.util.String
class. Okay, that may break something else elsewhere but in this exact case that should be enough.
If you don't want to do the thing above, you can make your own converters (see this handy tutorial) which will help you achieve your goal. And don't be afraid of making your own converter either, they're really easy to implement.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With