2011-09-19 3 views
14

Je suis confronté à un problème de désérialisation d'un fichier XML qui a été sérialisé avec succès avec le framework Simple XML Serialization (simpleframework.org).Exception avec désérialisation de structure XML simple

Il est an exception jeté:

org.simpleframework.xml.core.PersistenceException: Constructor not matched for class projet.sarelo.Note 

Ceci est l'appel:

Serializer serializer = new Persister(); 
File xmlFile = new File(path); 
ContactList contactList = serializer.read(ContactList.class, xmlFile); <== Error 

Mon ContactList.java

@Root(strict=false, name="ContacList") 
public class ContactList {  
    @ElementArray (name = "Contacts") 
    Contact [] contact;  
} 

Mon Note.java

public class Note { 
    @Element(required=false) 
    private String note; 

    public Note(String note) { 
     super(); 
     this.note = note; 
    } 

    public String getNote() { 
     return note; 
    } 
} 

Mon Contact.java

@Root 
public class Contact { 
@Attribute(name = "id") 
public String id;  

@Element(name="Nom", required=false)     
String name; 

@ElementArray(name="Phones", required=false) 
Phone [] phone; 

@ElementArray(name = "Emails", required=false) 
Email [] email; 

@ElementArray(name = "Adresses", required=false) 
Adresses [] adresses; 

@ElementArray(name = "Notes", required=false) 
Note [] note; 

public Contact(String id, String name) { 
    super(); 
    this.id = id; 
    this.name = name; 
} 

public String getName() { 
    return name; 
} 

public String getId(){ 
    return id; 
} 
} 

Et voici le fichier XML que j'essaie de désérialiser.

<ContactList> 
<Contacts length="5"> 
    <contact id="1"> 
    <Adresses length="0"/> 
    <Emails length="0"/> 
    <Notes length="1"> 
     <note> 
      <note>dgfdg</note> 
     </note> 
    </Notes> 
    </contact> 
    <contact id="2"> 
    <Adresses length="1"> 
     <adresses> 
      <city>Paris </city> 
      <postcode>751234 </postcode> 
      <state>France</state> 
      <street>Pignon</street> 
     </adresses> 
    </Adresses> 
    <Emails length="1"> 
     <email type="home"> 
      <home>[email protected]</home> 
     </email> 
    </Emails> 
    <Nom>Nicolas Sarkozy </Nom> 
    <Notes length="1"> 
     <note> 
      <note>Je suis le president de toute la france. Le grand president</note> 
     </note> 
    </Notes> 
    <Phones length="2"> 
     <phone> 
      <home>+33 1234</home> 
     </phone> 
     <phone> 
      <mobile>+33 0612</mobile> 
     </phone> 
    </Phones> 
    </contact> 
    ... 
</Contacts> 
</ContactList> 
+0

Pour votre information, des questions très similaires [ici] (http://stackoverflow.com/q/5894320/642706) et [ ici] (http://stackoverflow.com/q/16135304/642706) –

Répondre

40

No-Arg Constructeur

Je ne sais pas ce cadre XML particulier, mais, en général, vous avez besoin d'un constructeur qui ne prend aucun paramètre/arguments pour chaque classe que vous souhaitez être désérialisé. De tels constructeurs sont connus comme "no-arg", "0-argument", ou (formellement) nullary constructor.

Sinon, l'infrastructure ne peut pas instancier la classe.

+1

Merci @Timores. J'ai généré des constructeurs vides pour chaque classe et ça fonctionne maintenant. –

+0

Merci @Timores! J'ai eu un problème avec l'une de mes classes d'objets de données (la classe racine pour être exacte). Le constructeur était défini sur private, car j'utilisais une méthode statique "loadFromXml" dans la même classe pour instancier un objet. Longue histoire courte: vous ** avez besoin ** soit d'un constructeur No-Arg public ou d'un constructeur public annoté (voir le commentaire direct de Bourque à la question) afin que le programme désérialise correctement la source XML. – Igor

+0

@BasilBourque Je reçois cette erreur lors de l'exécution de proguard sur mon application. Pourriez-vous jeter un oeil à la [ma question] (https://stackoverflow.com/q/47407587/1889768). – Abbas

-2

je pense qu'il est préférable d'utiliser SAX pour analyser un fichier XML Voici un exemple d'analyse syntaxique:

Vous devez créer un analyseur de classe comme ceci:

{ public class DataXMLReader extends DefaultHandler { 



    public DataXMLReader() { 


    } 

    public void startElement(String uri, String name, String qName,Attributes atts) 
    { 
       if (name.trim().equalsIgnoreCase("window")) 
       { 
        atts.getValue("type_id") // to get proprietis 
       } 
       else if (name.trim().equalsIgnoreCase("component")) 
       { 

       } 


    } 



    public void endElement(String uri, String name, String qName) 

      throws SAXException { 

     if (name.trim().equalsIgnoreCase("component")) 
     { 
      if(Integer.parseInt(typeid)<=6) 
       idParent.remove(idParent.size()-1); 

     }  
      } 

     @Override 
     public void startDocument() throws SAXException { 
      // TODO Auto-generated method stub 
      super.startDocument(); 

      Log.e("StartDoc","Reading XML"); 
     } 
      public void endDocument() throws SAXException { 
       // TODO Auto-generated method stub 
       myBdd.close(); 
       Log.e("EndtDoc","End XML"); 

        } 

} 
} 

et ceci est un exemple appel XML depuis URL:

String url="http://vxbfdhbf.xml"; 
     try { 

      SAXParserFactory spf = SAXParserFactory.newInstance(); 
      SAXParser sp = spf.newSAXParser(); 
      XMLReader xr = sp.getXMLReader(); 
      URL sourceUrl = new URL(url); 

      HttpURLConnection connection = null; 
      connection = (HttpURLConnection)sourceUrl.openConnection(); 
      connection.setConnectTimeout(60000); 
      connection.setInstanceFollowRedirects(false); 
      connection.connect(); 



      DataXMLReader myXMLHandler = new DataXMLReader(this,"1"); 
      xr.setContentHandler(myXMLHandler); 

      xr.parse(new InputSource(connection.getInputStream())); 
      connection.disconnect(); 






     } catch (Exception e) { 

      Log.e("saxERR",""+e.toString()); 
     } 
+0

Merci pour l'aide @Yaz, mais le problème est maintenant résolu :) Je n'ai pas encore essayé SAX mais jetez un coup d'oeil à [Simple XML framework] (http://simple.sourceforge.net) et je suis sûr que vous ne ferez pas le regret. C'est calme simple. –

+0

@MohamedYaz Comme l'a dit San Francesco, [SimpleFramework.org] (http: //simple.sourceforge.net /) est vraiment simple pour ce genre de travail, en sérialisant les objets en XML. Une ou deux lignes de code peuvent faire tout ce travail SAX que vous montrez. –

+0

Pouvez-vous juste pointer la majeure partie du code et expliquer nécessaire pour résoudre le problème? – Phani

12

Vous n'avez pas besoin de supprimer des éléments du constructeur. Vous pouvez simplement ajouter quelque chose comme ceci:

public Contact(@Element (name = "id") String id, @Element (name = "name") String name) { 
... 

Il travaillait pour moi :)

+1

Juste une note ici, après l'annotation, vous devez également ajouter le '(nom =" ")' correspondant au nom de la variable que vous avez désérialisée. – Falkenfighter

+0

C'est la meilleure réponse à mon humble avis. J'ai oublié cela dans la documentation Simple-Framework, mais c'est ce que les tutoriels vous disent de faire. http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php#immutable Voir Constructor Injection. –

+0

Cela m'a aidé à comprendre mon problème. Mais je reçois cette exception pour le constructeur no/default. Cependant, l'ajout de tous les éléments au constructeur semble résoudre le problème. Cependant, j'ai un montant de code énorme à passer si je veux le faire. Y a-t-il une solution plus simple pour cela? – Abbas