0

I think I may of "zoomed in" too much with my XStream work, but I'm trying to marshall an XML stream, which contains a variety of large complex objects, and each of these objects tends to have lots of tags such as :

<name type="string">My Name</name>
<speed type="dice">2d6</speed>

So I created a "TypedString" object, to wrap up the concept of a string with a type attribute, like so:

import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
public class TypedString {
    @XStreamAsAttribute
    private String type;
    private String value;

    public TypedString(String type, String value) {
        this.type = type;
        this.value = value;
    }
    // getters omitted 
}

Now, I know this must be missing something - as how can I get the "value" variable set using the contents of the tag (e.g. for the first example shown above, type would be "string" and value would be "My Name").

I wrote a brief unit test for this :

public class TypedStringTest {
    private XStream xStream;

    @Before
    public void setUp() {
        xStream = new XStream();
        xStream.processAnnotations(TypedString.class);
        xStream.alias("name", TypedString.class);
    }

    @Test
    public void testBasicUnmarshalling() {
        TypedString typedString = (TypedString) xStream.fromXML("<name type=\"string\">Name</name>");
        assertEquals("string", typedString.getType());
        assertEquals("Name", typedString.getValue());
    }
}

Which fails on the second assertion.

Is there an annotation I need to add to the TypedString class to get it working ? Or have I really zoomed in too far here (e.g. should this all be done on annotations in the class containing these tags ?). The @XStreamAsAttribute annotation didn't look like it could be used from the parent tag - it needed to be defined on the object representing the tag in applied to, from what I could tell. Hence I made what is otherwise a glorified String, which I feel XStream should be marshalling without my implicit assistance.

In a nutshell, where have I got lost ?!

Phantomwhale
  • 1,789
  • 1
  • 16
  • 30
  • Having looked around the site for an answer, the best I'm seeing is converters - is there really no way of doing this with annotations in XStream? – Phantomwhale Jul 25 '11 at 08:03

2 Answers2

2
@XStreamAlias("name")
@XStreamConverter(value=ToAttributedValueConverter.class, strings={"value"})
public class TypedString {
    private String type;
    private String value;
}
mantrid
  • 2,830
  • 21
  • 18
  • 1
    Note that ToAttributedValueConverter is only since XStream version 1.4+ .. there's a hack for earlier versions :( https://stackoverflow.com/questions/23570817/xstream-node-with-attributes-and-text-node-in-xstream-1-3-1 – Black Aug 02 '18 at 02:36
0
@XStreamConverter(value=ToAttributedValueConverter.class, strings={"value"})
public class TypedString {
    @XStreamAsAttribute
    private String type;
    private String value;
}

It works for single line values.

If you have something like this the value will be some white spaces.

<name type="string">
    My Name
</name>

In this case value will be " ".

Rodolfo
  • 1,091
  • 3
  • 13
  • 35