我有一个需要序列化为XML的对象,其中包含以下字段:
List<String> tags = new List<String>();
XStream将它序列化很好(在一些别名之后),如下所示:
<tags>
<string>tagOne</string>
<string>tagTwo</string>
<string>tagThree</string>
<string>tagFour</string>
</tags>
尽管如此,这是可以的,但我希望能够将<string>
元素重命名为<tag>
。我无法从XStream网站上的别名文档中看到一种明显的方法。我错过了一些明显的东西吗?
答案 0 :(得分:12)
出于兴趣,我尝试了这样做,而没有编写我自己的转换器。基本上我只是为特定类别中的某个字段注册了CollectionConverter
的特殊指示版本。
相关摘要:
ClassAliasingMapper mapper = new ClassAliasingMapper(xstream.getMapper());
mapper.addClassAlias("tag", String.class);
xstream.registerLocalConverter(
Test.class,
"tags",
new CollectionConverter(mapper)
);
成熟的例子:
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));
}
}
未经测试,但这应该有效。否?
xstream.alias("tag", java.lang.String.class);
答案 1 :(得分:5)
我建议将List<String>
更改为List<Tag>
,其中Tag是一个基本上只包含字符串的域对象。然后你说:
xstream.alias("tag", org.goring.Tag.class);
你得到了你想要的。这样可以避免滚动自己的转换器。
答案 2 :(得分:2)
@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结果:
<example>
<myList>
<myField>aa</myField>
<myField>bb</myField>
</myList>
</example>
答案 3 :(得分:1)
为java.util.String
类添加别名。好的,这可能会破坏其他地方的其他东西,但在这种情况下应该足够了。
如果您不想做上述事情,可以制作自己的转换器(see this handy tutorial),这将有助于您实现目标。并且不要害怕制作自己的转换器,它们真的很容易实现。
答案 4 :(得分:0)
@XStreamConverter(value=ListToStringXStreamConverter.class, strings={"tag"})
List<String> tags = new List<String>();
和ListToStringXStreamConverter.java
public class ListToStringXStreamConverter implements Converter {
private String alias;
public ListToStringXStreamConverter(String alias) {
super();
this.alias = alias;
}
@SuppressWarnings("rawtypes")
@Override
public boolean canConvert(Class type) {
return true;
}
@Override
public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
@SuppressWarnings("unchecked")
List<String> list = (List<String>)source;
for (String string : list) {
writer.startNode(alias);
writer.setValue(string);
writer.endNode();
}
}
@Override
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
throw new UnsupportedOperationException("ListToStringXStreamConverter does not offer suport for unmarshal operation");
}
}
答案 5 :(得分:0)
对我来说,使用下面的代码,使用字符串:
xStream.alias("myTag", Person.class);
xStream.addImplicitCollection(Person.class, "myTag", "myTag", String.class);
public class Person{
private ArrayList<String> myTag;
// ...
}
<Person>
<myTag>atrcxb2102</myTag>
<myTag>sub3</myTag>
</Person>