Konrad Morawski
Konrad Morawski

Reputation: 8394

How to deserialize an xml representing a root-level array with Simple Xml Framework

I am using Simple XML framework for deserialization on Android.

The xml that I need to deserialize is roughly like so:

<?xml version="1.0" encoding="UTF-8"?>
<elements type="array">
    <element foo="x"/>
    <element foo="y"/>
</elements>

In other words, it is an array right on the root level.

How to define a model class that I can deserialize it to?

I tried something as follows:

@Root (name = "elements")
public class Elements implements Serializable {
   private static final long serialVersionUID = ...

   @ElementArray (name = "element")
   private List<Element> elements;
}

But it fails, since there is no type field to account for the type attribute in the xml.

Adding a type field (just for the sake of satisfying the deserializer) doesn't resolve the issue, generates another error instead: org.simpleframework.xml.core.InstantiationException: Type is not an array interface java.util.List for field 'elements' ...

What's the proper way of implementing the Elements class? Even though under time pressure, I'd like a clean solution, not some hackish workaround (that I'd probably come up with).

Upvotes: 0

Views: 1028

Answers (2)

Konrad Morawski
Konrad Morawski

Reputation: 8394

The correct solution is:

public class Elements implements Serializable {
   private static final long serialVersionUID = ...

   @Attribute (name = "type", required = false)
   private String type;

   @ElementList (name = "elements", entry = "element", inline = true)
   private List<Element> elements;
}

J. Marcos's answer was correct in pointing out that I should have used ElementList and the inline attribute.

What was still missing is removing the Root annotation (I guess it clashes with the idea of inlining the list), and adding an entry attribute, which specifies the name of the array element.

Perhaps it is not required if the tag is of the same name as the field (like in my contrived example), but if they differ (say, elementItem in the class and element_item in the xml), it apparently is.

Upvotes: 1

jmarcoscl
jmarcoscl

Reputation: 11

In your Elements class, you should use @ElementList and add an attribute named "type"

@ElementList(name="elements", inline=true)
private List<Element> elements;

@Attribute(name="type")
private String type;

Also, if you don't wanna bother about the type attribute in the xml, just add required=false, like this:

@Attribute(name="type", required=false)

Upvotes: 1

Related Questions