[Simple-support] Serialize and deserialize undefined Xml attributes into a HashMap<String, String>
Brought to you by:
niallg
|
From: Christian K. <c....@sp...> - 2012-11-14 09:44:35
|
Hi SimpleXml Team,
I use SimpleXml frequently on android and it is great.
Now I have a question how to do that job:
All XML attributes that are not defined in the Java class with
@Attribute should be serialized and deserialized into a
HashMap<String,String>.
Here is an example:
This is out test class "Car"
@Root(strict = false, name = "Car")
public class Car
{
@Attribute
public double length;
@Attribute
public String color;
@Attribute
public int nrOfDoors;
public HashMap<String, String> furtherAttributes = new
HashMap<String, String>();
}
And this is the serialization test method:
public void testCar() throws Exception
{
Car car = new Car();
car.color = "red";
car.length = 4.3;
car.nrOfDoors = 4;
car.furtherAttributes.put("fuelConsumption", "7.8");
car.furtherAttributes.put("topSpeed", "190");
Serializer serializer = new Persister();
StringWriter stringwriter = new StringWriter();
serializer.write(car, stringwriter);
String xml = stringwriter.toString();
}
The result of the serialization is:
<Car color="red" length="4.3" nrOfDoors="4"/>
So the furtherAttributes of the HashMap are missing. The result should be:
<Car color="red" length="4.3" nrOfDoors="4" fuelConsumption="7.8"
topSpeed="190" />
And the way back should also work:
So if we have a xml like this:
<Car color="green" length="3.3" nrOfDoors="2" topSpeed="190" brand="audi" />
After the deserialization the HashMap "furtherAttributes" should have
the two undefined attributes "topSpeed" and "brand".
I already read the mailing list and some SimpleXml test cases.
So I try implement a new Strategy to solve that problem.
The AnyAttributeRegistryStrategy looks for classes with annotation
"AnyClass" and inside that class searches for the annotation "Any".
The annotation "Any" is used to tag the HashMap, where the futher
attributes should be serialized to.
public class AnyAttributeRegistryStrategy extends RegistryStrategy
{
public AnyAttributeRegistryStrategy(Registry registry)
{
super(registry);
}
@Override
public boolean write(Type type, Object value, NodeMap<OutputNode> node,
@SuppressWarnings("rawtypes") Map map) throws Exception
{
if (value.getClass().getAnnotation(AnyClass.class) != null)
{
for (Field field : value.getClass().getFields())
{
if (field.getAnnotation(Any.class) != null)
{
Object mapObject = field.get(value);
if (mapObject instanceof Map<?, ?>)
{
Map<?, ?> keyValueMap = (Map<?, ?>) mapObject;
for (Entry<?, ?> keyValuePair :
keyValueMap.entrySet())
{
if (keyValuePair.getKey() != null
&& keyValuePair.getValue() != null)
{
node.getNode().setAttribute(
keyValuePair.getKey().toString(),
keyValuePair.getValue().toString());
}
}
}
}
}
}
return super.write(type, value, node, map);
}
}
And this is the Car class with the new annotations:
@AnyClass
@Root(strict = false, name = "Car")
public class Car
{
@Attribute
public double length;
@Attribute
public String color;
@Attribute
public int nrOfDoors;
@Any
public HashMap<String, String> furtherAttributes = new
HashMap<String, String>();
}
Now the serialisation of the class to xml works.
But I do not have a correctly working solution for the deserialisation.
Do you have any ideas?
Thanks for you help
Christian Klotz
|