Re: [Simple-support] Serialize and deserialize undefined Xml attributes into a HashMap<String, Stri
Brought to you by:
niallg
|
From: Christian K. <c....@sp...> - 2012-11-15 13:28:15
|
Hi Niall,
thanks for your quick response.
Now I have implemented an Visitor.
In the read method, I can get a nodeMap with all xml attributes.
I can also detect via refection which attributes have the annotation
@Attribute.
All other attributes should be stored in the HashMap "furtherAttributes".
But I don't known how to put them into the HashMap "furtherAttributes".
I do not have the resulting car object. Do you have any tip?
public class AnyAttributesVisitor implements Visitor
{
@Override
public void read(Type type, NodeMap<InputNode> nodeMap) throws
Exception
{
// nodeMap contains all xml attributes of the car xml
// Content is:
// {color=attribute color='red', length=attribute length='4.3',
// nrOfDoors=attribute nrOfDoors='4', fuelConsumption=attribute
// fuelConsumption='7.8', topSpeed=attribute topSpeed='190'}
//Detect attributes with Annotation @Attribute
ArrayList<String> attributesWithAnnotation = new
ArrayList<String>();
for (Field field : type.getType().getFields())
{
if (field.getAnnotation(Attribute.class) != null)
{
String name = field.getAnnotation(Attribute.class).name();
if (name == null || name.equals(""))
{
name = field.getName();
}
attributesWithAnnotation.add(name);
}
}
for (String entry : nodeMap.getNode().getAttributes())
{
if (!attributesWithAnnotation.contains(entry))
{
String furtherAttributeKey = entry;
String furtherAttributeValue = nodeMap.getNode()
.getAttribute(entry).getValue();
// TODO: Add Key and Value to the Hashmap furtherAttributes
nodeMap.remove(furtherAttributeKey);
}
}
}
@Override
public void write(Type type, NodeMap<OutputNode> nodeMap) throws
Exception
{
}
}
This is my test case:
public void testCarDeserialisation() throws Exception
{
String xml = "<Car color=\"red\" length=\"4.3\" nrOfDoors=\"4\"
fuelConsumption=\"7.8\" topSpeed=\"190\" />";
Serializer serializer = new Persister(new VisitorStrategy(
new AnyAttributesVisitor()));
Car car = serializer.read(Car.class, xml);
}
Thanks Christian
Am 15.11.2012 00:33, schrieb Niall Gallagher - Yieldbroker:
> I think a Visitor would be simpler than a Strategy, there are many test cases doing this very thing. Just browse through them, I am sure you will find a template. You can browse them here http://simple.svn.sourceforge.net/viewvc/simple/trunk/download/stream/src/test/java/org/simpleframework/xml/
>
> -----Original Message-----
> From: Christian Klotz [mailto:c....@sp...]
> Sent: Wednesday, 14 November 2012 8:26 PM
> To: sim...@li...
> Subject: [Simple-support] Serialize and deserialize undefined Xml attributes into a HashMap<String, String>
>
> 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
>
>
>
>
>
>
> ------------------------------------------------------------------------------
> Monitor your physical, virtual and cloud infrastructure from a single web console. Get in-depth insight into apps, servers, databases, vmware, SAP, cloud infrastructure, etc. Download 30-day Free Trial.
> Pricing starts from $795 for 25 servers or applications!
> http://p.sf.net/sfu/zoho_dev2dev_nov
> _______________________________________________
> Simple-support mailing list
> Sim...@li...
> https://lists.sourceforge.net/lists/listinfo/simple-support
>
--
Mit freundlichen Grüßen / Kind regards
Christian Klotz
Software Engineer
SPEDION GmbH
Industriestraße 7
D - 63829 Krombach
Fon: +49 (0) 6024 / 50990-132
Fax: +49 (0) 6024 / 50990-121
mailto:c....@sp...
SPEDION GmbH - Industriestraße 7 - 63829 Krombach - Germany
Amtsgericht Aschaffenburg, HRB 8647
Geschäftsführer: Günter Englert, Wolfram Grohse
|