XStream refuses to add the "resultState" field as attribute in the output xml below (see screenshot), yet it does it correctly for the "order" and "name" fields. Any idea why?

Code:

xstream.useAttributeFor(Result.class, "name");
xstream.useAttributeFor(Result.class, "order");
xstream.useAttributeFor(Result.class, "resultState");

With: - Result.class, the parent class of ScenarioResult, TestCaseResult, PhaseResult and TaskResult shown in the xml output below. - "resultState", a field of Result.class and of type ResultState (it's an enum type)

XML output (please see screenshot attached as plain xml text doesn't show properly on the post): enter image description here

有帮助吗?

解决方案

The problem is that the ResultState class is an enum type and that Xstream does not know how to pass enums as attributes without a little help. The solution is to create a converter class for the enum and register it to the xstream instance as explained in this SO post: Serialization problem with Enums at Android

Check also this post for a converter implementation that uses generics: enums as attributes

My solution combines bits from those two posts as shown below (note I made the converter private static but it works the same if put in it's own class file):

private static class EnumSingleValueConverter<T extends Enum<T>> 
   extends AbstractSingleValueConverter { 

    private Class<T> enumType; 

    public static <V extends Enum<V>> SingleValueConverter 
    create(Class<V> enumClass) { 
        return new EnumSingleValueConverter<V>(enumClass); 
    } 

    private EnumSingleValueConverter(Class<T> newEnumType) { 
        this.enumType = newEnumType; 
    } 

    public boolean canConvert(Class type) { 
        return type == enumType; 
    } 

    public Object fromString(String str) { 
        return Enum.valueOf(enumType, str); 
    } 

    public String toString(Object obj) { 
        return obj.toString(); 
    } 
} 

The rest of the code doesn't change except we add one line for the registration bit:

xstream.registerConverter(EnumSingleValueConverter.create(ResultState.class));
xstream.useAttributeFor(Result.class, "name");
xstream.useAttributeFor(Result.class, "order");
xstream.useAttributeFor(Result.class, "resultState");

As an example, line 11 in the screenshot now looks like this:

<TaskResult name="CheckValue" resultState="FAILURE" order="0"/>

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top