11

我有一个需要序列化为 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 站点上的别名文档中,我看不到明显的方法。我错过了一些明显的东西吗?

4

6 回答 6

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);
于 2009-11-24T16:31:37.630 回答
5

我建议将 更改List<String>为 a List<Tag>,其中 Tag 是一个域对象,基本上只包含一个字符串。然后你说:

xstream.alias("tag", org.goring.Tag.class);

你得到你想要的。这避免了必须滚动您自己的转换器。

于 2009-11-24T17:35:24.727 回答
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>
于 2011-02-23T02:32:26.870 回答
1

为类添加别名java.util.String。好的,这可能会破坏其他地方的其他东西,但在这种情况下,这应该足够了。

如果您不想做上述事情,您可以制作自己的转换器(请参阅这个方便的教程),这将帮助您实现目标。也不要害怕制作自己的转换器,它们真的很容易实现。

于 2009-11-24T16:30:51.253 回答
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");
}

}
于 2012-10-01T14:21:44.490 回答
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>
于 2016-07-02T15:14:04.223 回答