2015-04-08 1 views
0

J'essaye de désérialiser un fichier XML en objets Java en utilisant simpleXML. Tout fonctionnait bien jusqu'à ce que je devais utiliser un ElementMap. Cela fait partie de mon fichier XML:Désérialise les éléments XML en Java Map

<piece composer="Me" date="Yesterday" title="Important work"> 
    <editions> 
     <edition name="My Name" date="2015" description="A single page"> 
      <pages> 
       <page fileName="page01.jpg" /> 
      </pages> 
     </edition> 
     <edition name="My Name again" date="2015" description="Another single page"> 
      <pages> 
       <page fileName="page01.jpg" /> 
      </pages> 
     </edition> 
    </editions> 
    <layers> 
     <layer name="Annotations" color="#FF0000" description="Empty" id="anno" /> 
     <layer name="Information" color="#00FF00" description="Empty" id="info" /> 
    </layers> 
</piece> 

La classe Java correspondant ressemble à ceci:

@Root 
public class Piece { 
    @Attribute 
    private String composer; 
    @Attribute 
    private String title; 
    @Attribute 
    private String date; 

    @ElementList 
    private List<Edition> editions; 

    @ElementMap(key = "id", attribute = true) // Relevant 
    private Map<String, Layer> layers;  // Lines 

    public static Piece loadFromAsset(Context context, String fileName) throws Exception { 
     Serializer serial = new Persister(); 
     return serial.read(Piece.class, context.getResources().getAssets().open(fileName)); 
    } 
} 

Et enfin la classe de couche:

public class Layer { 
    @Attribute 
    private String id; 
    @Attribute 
    private String name; 
    @Attribute 
    private String description; 
    @Attribute 
    private String color; 
} 

Après chargement du fichier XML du La carte contient les deux clés, mais elles pointent toutes les deux vers null au lieu des objets de calque réels.

Répondre

0

Je ne suis pas SimpleFrawmerow utilisateur, donc je ne suis pas garantir cela fonctionnera, mais vous devriez probablement spécifier plus attirbutes des applications ElementMap:

@ElementMap(key = "id", attribute = true, keyType=String.class 
      ,valueType=Layer.class) 

Si cela ne vous aide pas à gérer la liste à la carte vous conversion. Le problème est que votre fichier xml contient réellement une liste d'éléments de calque au lieu de la carte (il n'y a pas de paires d'éléments de clé/valeur).

Vous pouvez ajouter à votre champ supplémentaire de classe Piece pour stocker cette liste et avoir le champ de carte construite en utilisant le:

class Piece { 
    ... 
    @ElementList //only for solution B, for a do not use this annotation 
    List<Layer> layers; 

    @Transient //importatnt as it does not go into xml directly 
    private Map<String, Layer> layersMap;   
} 

maintenant il y a deux approches:

A) utiliser accesseurs pour liste des couches, et à l'intérieur des méthodes construire le contenu de la liste carte selon les besoins:

@ElementList 
    public void setLayers(Collection<Layer> layers) { 
     layersMap = new HashMap<>(); 
     for (Layer l : layers) layersMap.put(l.getId(),l); 
    }   

    @ElementList 
    public Collection<Layer> getLayers() { 
     return layersMap.values(); 
    } 

B) utiliser le mécanisme du cycle de vie de sérialisation (Persistance et engager annotations). Dans une méthode appelée avant la sérialisation, vous créez le contenu de la liste en utilisant la carte dans l'autre, vous remplissez la carte en utilisant les valeurs de la liste. Personnellement, je préfère les getters/setters car vous pouvez cacher l'élément 'layers'. Enfin, vous pouvez utiliser le convertisseur pour contrôler complètement le processus, mais je crois que ce qui précède est plus facile et moins bavard.

+0

Merci beaucoup! J'ai fini par utiliser votre méthode A avec à peu près exactement la même syntaxe. Les autres solutions ne fonctionnent pas moins, mais simple est belle. ;-) – sonovice