2011-09-19 11 views
14

Tengo un problema para deserializar un archivo XML que se haya serializado con éxito con el marco Simple XML Serialization (simpleframework.org).Excepción con deserialización de marco XML simple

Hay an exception lanzados:

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

Ésta es la llamada:

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

Mi ContactList.java

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

Mi Note.java

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

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

    public String getNote() { 
     return note; 
    } 
} 

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

Y este es el archivo XML que estoy tratando de deserializar.

<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, muy similares [aquí] (http://stackoverflow.com/q/5894320/642706) y [ aquí] (http://stackoverflow.com/q/16135304/642706) –

Respuesta

40

n-Arg Constructor

No sé este marco XML particular, pero, por lo general se necesita un constructor que no toma parámetros/argumentos para cada clase que desea ser deserializado. Tales constructores se conocen como "no-arg", "0-argumento", o (formalmente) nullary constructor.

De lo contrario, el marco no puede instanciar la clase.

+1

Gracias @Timores. Genere constructores vacíos para cada clase y ahora está funcionando. –

+0

Gracias @Timores! Tuve un problema con una de mis clases de objetos de datos (la clase de raíz para ser exactos). El constructor que tenía se estableció en privado, porque estaba usando un método estático "loadFromXml" en la misma clase para crear una instancia de un objeto. Para resumir: necesitas ** un constructor público No-Arg o un constructor public anotado (ver el comentario directo de Bourque a la pregunta) para que el programa deserialice correctamente la fuente XML. – Igor

+0

@BasilBourque Recibo este error cuando ejecuto Proguard en mi aplicación. ¿Podría echar un vistazo a [mi pregunta] (https://stackoverflow.com/q/47407587/1889768). – Abbas

-2

creo que es mejor usar SAX para analizar un XML Este es un ejemplo de análisis:

Es necesario crear un analizador clase como esta:

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

        } 

} 
} 

y esto es un ejemplo de llamar a XML desde la 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

Gracias por su ayuda @Yaz, pero el problema está resuelto :) No he probado SAX todavía, pero eche un vistazo a [Simple XML framework] (http://simple.sourceforge.net) y estoy seguro de que no lo hará lamentar. Es muy simple. –

+0

@MohamedYaz Como dijo San Francesco, [SimpleFramework.org] (http: //simple.sourceforge.net /) realmente es simple para este tipo de trabajo, serializar objetos a XML. Una o dos líneas de código pueden hacer todo el trabajo de SAX que muestre. –

+0

¿Puede simplemente señalar la mayor parte del código y explicar lo necesario para resolver el problema? – Phani

12

No tiene que eliminar elementos del constructor. Usted puede añadir algo como esto:

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

que estaba trabajando para mí :)

preguntas
+1

Solo una nota aquí, después de la anotación también debe agregar el '(nombre =" ")' que coincida con el nombre de la variable que deserializó. – Falkenfighter

+0

Esta es la mejor respuesta en mi humilde opinión. Pasé por alto esto en la documentación de Simple-Framework, pero es lo que los tutoriales te dicen que hagas. http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php#immutable Vea Constructor Injection. –

+0

Esto me ayudó a entender mi problema. Pero obtengo esta excepción para el constructor no/default. Sin embargo, agregar todos los elementos al constructor parece resolver el problema. Sin embargo, tengo una cantidad de código enorme para procesar si quiero hacerlo. ¿Hay una solución más simple para eso? – Abbas

Cuestiones relacionadas