I would like to know how I can implement optional attributes within XStream.
Here is the XML:
<AttributeValues>
<AttributeValue attributeId='id01' languageId='en'>20</AttributeValue>
<AttributeValue attributeId='id02'>99</AttributeValue>
<AttributeValue attributeId='id03' languageId='en'78</AttributeValue>
<AttributeValue attributeId='id04' languageId='en'>14</AttributeValue>
<AttributeValue attributeId='id05'>9</AttributeValue>
</AttributeValues>
After the parsing process, not every 'AttributeValue' item has a languageId
.
XStream sets such empty values to 'null'. But I would like to have it as an empty string "".
How do I implement this?
You can achieve your goal using custom Converter
class.
There will be a bit of guessing here since you haven't posted code for AttributeValues
and AttributeValue
class. I will use following classes:
AttributeValues
class:
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import java.util.ArrayList;
import java.util.List;
@XStreamAlias("AttributeValues")
public class AttributeValues
{
@XStreamImplicit(itemFieldName="AttributeValue")
public List<AttributeValue> Values;
public AttributeValues()
{
Values = new ArrayList<AttributeValue>();
}
public void add(String id, String lg, String value)
{
AttributeValue item = new AttributeValue();
item.attributeId = id;
item.languageId = lg;
item.value = value;
Values.add(item);
}
}
AttributeValue
class:
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
public class AttributeValue
{
@XStreamAsAttribute
public String attributeId;
@XStreamAsAttribute
public String languageId;
public String value;
}
And here is AttributeValueConverter
class:
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
public class AttributeValueConverter implements Converter
{
public boolean canConvert(Class clazz) {
return AttributeValue.class == clazz;
}
public void marshal(Object object, HierarchicalStreamWriter hsw, MarshallingContext mc) {
AttributeValue av = (AttributeValue) object;
hsw.addAttribute("attributeId", av.attributeId);
hsw.addAttribute("languageId", av.languageId);
hsw.setValue(av.value);
}
public Object unmarshal(HierarchicalStreamReader hsr, UnmarshallingContext uc) {
AttributeValue av = new AttributeValue();
av.attributeId = hsr.getAttribute("attributeId");
av.languageId = hsr.getAttribute("languageId");
if (av.languageId == null) av.languageId = "";
av.value = hsr.getValue();
return av;
}
}
Serialization:
AttributeValues obj = new AttributeValues();
obj.add("id01", "en", "20");
XStream xstream = new XStream();
xstream.autodetectAnnotations(true);
xstream.registerConverter(new AttributeValueConverter());
String s = xstream.toXML(obj);
Unserialization:
XStream xstream = new XStream();
xstream.autodetectAnnotations(true);
xstream.registerConverter(new AttributeValueConverter());
AttributeValues newobj = (AttributeValues)xstream.fromXML(s);