Jeevan
Jeevan

Reputation: 8772

Handle deserialization with convertor and map different tags under a xml tag to single list

I am using simple xml framework and I have a situation.

My xml looks as below.

<root>
    <title> something </title>
    <desc> something more </desc>
     <mixture>
        <nodeA id="4" type="A">
        <nodeB id="5" type="B">
        <nodeB id="6" type="C">
        <nodeB id="7" type="D">
        <nodeB id="8" type="E">
        <nodeB id="9" type="F">
    </mixture>
</root>

I have defined class and annotation as below.

@Root(strict=false,name="root")
class Root{

    @Element
    private String title;

    @Element
    private String desc;

    @ElementList(required=false,inline=true)
    @Path("mixture")
    ArrayList<GenericNode> genericNodes;
}

@Root(strict = false)
@Convert(Convertor.class)
class GenericNode{
 //no annotation are defined
 //we ll handle the conversion ourself in "Convertor" class
}

Problem is I want to map all those nodes inside mixture to a list. But custom convertor that i have defined is not getting called. If i remove attribute required on ArrayList<GenericNode> genericNodes; then deserializing fails with an exception.

May be the problem is since i have not defined name or entry attribute for genericNodes. Framework is failing to map it properly. How can i solve the issue?

Note: 1. I am using AnnotationStratergy

Serializer serializer = new Persister(new AnnotationStrategy());

2. I dont want to use ElementUnion attribute because different kinds of node that i need to map are close to 10 tags

Upvotes: 0

Views: 168

Answers (1)

ollo
ollo

Reputation: 25350

Please post the exception, else it's difficult to say where the problem comes from.

  1. all your nodes aren't closed!
  2. @ElementList(required = true, name = "mixture") is possible for genericNodes

I have deserialized the XML successfully using this code:

GenericNode class:

@org.simpleframework.xml.Root(strict = false)
@Convert(GenericNodeConverter.class)
public class GenericNode
{
    private String name;
    private int id;
    private String type;


    // ...
}

I've added an additional field name where the node name (nodeA or nodeB) is stored. This field ist not required.

Root class:

@org.simpleframework.xml.Root(strict = false, name = "root")
class Root
{
    @Element
    private String title;

    @Element
    private String desc;

    @ElementList(required = true, name = "mixture")
    ArrayList<GenericNode> genericNodes;

    // ...
}

And here's the converter:

GenericNodeConverter class:

public class GenericNodeConverter implements Converter<GenericNode>
{
    @Override
    public GenericNode read(InputNode node) throws Exception
    {
        GenericNode gn = new GenericNode();

        gn.setId(Integer.valueOf(node.getAttribute("id").getValue()));
        gn.setType(node.getAttribute("type").getValue());
        gn.setName(node.getName());

        return gn;
    }


    @Override
    public void write(OutputNode node, GenericNode value) throws Exception
    {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}

Input XML:

(all tags are closed)

<root>
    <title> something </title>
    <desc> something more </desc>
     <mixture>
         <nodeA id="4" type="A"></nodeA>
         <nodeB id="5" type="B"></nodeB>
         <nodeB id="6" type="C"></nodeB>
         <nodeB id="7" type="D"></nodeB>
         <nodeB id="8" type="E"></nodeB>
         <nodeB id="9" type="F"></nodeB>
    </mixture>
</root>

This works just fine.

I guess your converter doesn't get called because of the unclosed tags.

Upvotes: 3

Related Questions