Frage

Here's a snippet of XML that I'd like to deserialize with SimpleFramework:

<rs><r>
   <id>23</id>
   <bar>blargh</bar>
   <c><v>value 1</v></c>
   <c><v>value 2</v></c>
   <c><v>yet another value</v></c>
   <c><v>moar value</v></c>
</r></rs>

What I would like to end up with is an ElementList containing the contents of all the elements. I'm imagining something like:

@Root(strict=false)
public static class Foo {
    @Element(name="id")
    public int id;
    @Element(name="bar")
    public String info;
    @Path("c")
    @ElementList(entry="v", inline=true, required=false, empty = false)
    public List<String> values;
}

What I'm trying to do is reach down past the "c" element and directly into the "v" element for each member of the list. The above code doesn't do it. I want the @Path("c") statement to apply to each element in the list, but I can't figure out how to make the work.

War es hilfreich?

Lösung

I see two problems here:

  1. <rs><r>...</r></rs> are nested tags of the root element (not sure if @Path can handle this ...)
  2. the two tags of each entry (<c><v>...</v></c>) are not possible through @ElementList annotations (and @Path can't be set for each entry)

As a solution you can write two wrapper classes:

  • One, that wraps the root-node
  • Another one, that's put in the list, wrapping each a entry

And here comes the implementation:

Class FooWrapper

This class wraps a Foo class; you get rs-tag through the wrapper and the r-tag with the actual object.

@Root(name = "rs")
public class FooWrapper
{
    @Element(name = "r", required = true)
    private Foo f;


    public FooWrapper(Foo f) // Required just in case you want to serialize this object
    {
        this.f = f;
    }

    FooWrapper() { } // At least a default ctor is required for deserialization
}

Class Foo

Nothing special here. Only the type of the list entries is changed to the EntryWrapper.

@Root(strict = false)
public class Foo /* A */
{
    @Element(name = "id")
    public int id; /* B */
    @Element(name="bar")
    public String info;
    @ElementList(entry="c", inline=true, required=false, empty = false)
    public List<EntryWrapper> values; // Replacing the String with the EntryWrapper

    // ...
}
  • /* A */: In your code, this was static too, i've just removed it since i put it into a own class file.
  • /* B */: Better: encapsulate the fields, make them private and write getter / setter.

Class EntryWrapper

Each entry in the list is wrapped into such a wrapper object. Btw. no need to expose this class public.

public class EntryWrapper
{
    @Element(name = "v")
    private String value;


    public EntryWrapper(String value)
    {
        this.value = value;
    }

    EntryWrapper() { } // Once again, at least one default ctor is required for deserialization

    // ...
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top