2011-09-19 19 views
14

Sto affrontando un problema per deserializzare un file XML che è stato serializzato con successo con il framework Simple XML Serialization (simpleframework.org).Eccezione con deserializzazione del framework XML semplice

C'è an exception gettato:

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

Questa è la chiamata:

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

mio ContactList.java

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

mio Note.java

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

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

    public String getNote() { 
     return note; 
    } 
} 

mio 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; 
} 
} 

E questo è il file XML che sto cercando di deserializzare.

<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

FYI, molto simili [qui] (http://stackoverflow.com/q/5894320/642706) e [ qui] (http://stackoverflow.com/q/16135304/642706) –

risposta

40

costruttore no-arg

Non so questo particolare quadro XML, ma, di solito è necessario un costruttore che non accetta parametri/argomenti per ogni classe che si desidera essere deserializzato. Tali costruttori sono noti come "no-arg", "0-argument" o (formalmente) nullary constructor.

In caso contrario, il framework non può creare un'istanza della classe.

+1

Grazie a @Timores. Ho generato costruttori vuoti per ogni classe e ora funziona. –

+0

Grazie a @Timores! Ho avuto un problema con una delle mie classi di oggetti dati (la classe radice per essere esatta). Il costruttore che aveva era impostato su privato, perché stavo usando un metodo statico "loadFromXml" nella stessa classe per istanziare un oggetto. Per farla breve: tu ** hai bisogno ** di un costruttore pubblico No-Arg o di un costruttore pubblico annotato (vedi il commento diretto di Bourque alla domanda) per fare in modo che il programma deserializzi correttamente la sorgente XML. – Igor

+0

@BasilBourque Ricevo questo errore quando eseguo proguard sulla mia app. Potresti dare un'occhiata alla [mia domanda] (https://stackoverflow.com/q/47407587/1889768). – Abbas

-2

penso che sia meglio usare SAX per l'analisi di un XML Questo è un esempio di parsing:

È necessario creare un parser classe come questa:

{ 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"); 

        } 

} 
} 

e questo è un esempio per chiama XML dall'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

Grazie per l'aiuto @Yaz, ma il problema è ora risolto :) Non ho ancora provato SAX ma do un'occhiata a [Simple XML framework] (http://simple.sourceforge.net) e sono sicuro che non lo farai rimpiangere. È semplice e tranquillo. –

+0

@MohamedYaz Come disse San Francesco, [SimpleFramework.org] (http: //simple.sourceforge.net /) è davvero semplice per questo tipo di lavoro, serializzando oggetti in XML. Una o due righe di codice possono fare tutto ciò che SAX lavora mostrandole. –

+0

Puoi semplicemente indicare la maggior parte del codice e spiegare necessario per risolvere il problema? – Phani

12

Non è necessario eliminare le cose dal costruttore. Si può solo aggiungere qualcosa di simile:

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

che stava lavorando per me :)

domande
+1

Solo una nota qui, dopo l'annotazione devi anche aggiungere il '(name =" ")' corrispondente al nome della variabile che hai deserializzato. – Falkenfighter

+0

Questa è la risposta migliore IMHO. Ho trascurato questo nella documentazione di Simple-Framework, ma è quello che le tutorials ti dicono di fare. http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php#immutable Vedi Constructor Injection. –

+0

Questo mi ha aiutato a capire il mio problema. Ma sto ottenendo questa eccezione per costruttore no/default. Tuttavia, l'aggiunta di tutti gli elementi al costruttore sembra risolvere il problema. Tuttavia ho un codice di enorme entità da passare se voglio farlo. C'è una soluzione più semplice per questo? – Abbas

Problemi correlati