I'm having trouble parsing xml with simple xml framework. I want to store category id and list of tournaments inside a Map/hashMap how can I do that? I followed the tutorial on simple xml but it doesnt work for me.
I stored it in a list like this:
@ElementList(entry = "Category", inline = true, required = false)
List<Category> category;
but now I wanna store it in a map.
Here is xml:
Tutorial that I followed:
Any help would be appreciated, tnx.
It's not possible by Annoations like @ElementList
or @ElementMap
, but using a Converter
is still an (good) option.
Going that way means: Implementing a Converter for Tournaments
which merges the Category-Id / Tournament List pair.
And here is how this is done:
First the necessary (data-) classes.
@Root(name = "Tournament")
public class Tournament
{
@Text
private String data;
public Tournament(String data)
{
this.data = data;
}
private Tournament() { /* Required */ }
// ...
}
Note: I gave the Tournament
some data string, since the real data isn't shown. However, actually it doesn't matter what data it contains.
@Root(name = "Category")
public class Category
{
private String id;
// ...
}
@Root(name = "Tournaments")
@Convert(TournamentsConverter.class) // Specify the Converter used for this class
public class Tournaments
{
private Map<String, List<Tournament>> tournaments;
public Tournaments()
{
tournaments = new HashMap<>();
}
protected void put(String id, List<Tournament> tournaments)
{
this.tournaments.put(id, tournaments);
}
// ...
}
The @Convert
will use the following Converter
for serialization / deserialization of Tournaments
. I haven't implemented the serialization part in this example (it's not difficult though).
Important: @Convert
requires an AnnotationStrategy
(see example below)!
public class TournamentsConverter implements Converter<Tournaments>
{
private final Serializer serializer = new Persister();
@Override
public Tournaments read(InputNode node) throws Exception
{
Tournaments tournaments = new Tournaments();
InputNode childNode = node.getNext();
// Iterate over all childs of 'Tournaments'
while( childNode != null )
{
if( childNode.getName().equals("Category") == true )
{
final String categoryId = childNode.getAttribute("category_id").getValue();
List<Tournament> tournamentList = new ArrayList<>();
InputNode child = childNode.getNext();
// Iterate over all childs of 'Category'
while( child != null )
{
// Use a Serializer to read the nodes data
Tournament tournament = serializer.read(Tournament.class, child);
tournamentList.add(tournament);
child = childNode.getNext();
}
// Insert the Id / Tournament's pair
tournaments.put(categoryId, tournamentList);
}
childNode = node.getNext();
}
return tournaments;
}
@Override
public void write(OutputNode node, Tournaments value) throws Exception
{
// Implement as needed
throw new UnsupportedOperationException("Not supported yet.");
}
}
All the "magic" is done by the Converter:
Tournaments
child nodesCategory
id
Tournament
's to a listid
/ List of Tournament
to the result Tournaments
As shown above, it's possible to use a Serializer
for (de-)serialization of nodes. No need to implement that by hand.
Finally, here's an example. Please note the AnnotationStrategy
.
Serializer ser = new Persister(new AnnotationStrategy());
final String xml = "<Tournaments>\n"
+ " <Category category_id=\"289\">\n"
+ " <Tournament>aaaa</Tournament>\n"
+ " </Category>\n"
+ " <Category category_id=\"32\">\n"
+ " <Tournament>bbbd</Tournament>\n"
+ " <Tournament>cccc</Tournament>\n"
+ " </Category>\n"
+ "</Tournaments>";
Tournaments t = ser.read(Tournaments.class, xml);
System.out.println(t);
Output:
Using generated toString()
added to each class.
Tournaments{tournaments={289=[Tournament{data=aaaa}], 32=[Tournament{data=bbbd}, Tournament{data=cccc}]}}
The problem is that you are trying to create a structure like Map<String, <List<Tournament>>
and that doesn't seem to be possible with the ElementMap
annotation. You need sort of an ElementMapList
annotation. Maybe you can file an issue and Mr. Gallagher can add that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With