2011-09-19 14 views
14

Mam do czynienia z problemem deserializacji pliku XML, który został pomyślnie zserializowany w ramach Simple XML Serialization (simpleframework.org).Wyjątek z prostą deserializacją struktury XML XML

Istnieje an exception rzucony:

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

To jest wezwanie:

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

Moja ContactList.java

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

My Note.java

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

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

    public String getNote() { 
     return note; 
    } 
} 

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

I to jest plik XML Próbuję deserializowania.

<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, bardzo podobne pytania [tutaj] (http://stackoverflow.com/q/5894320/642706) i [ tutaj] (http://stackoverflow.com/q/16135304/642706) –

Odpowiedz

40

No-Arg Konstruktor

Nie znam tej konkretnej ramy XML, ale zazwyczaj trzeba konstruktora, który nie bierze Parametry/argumenty dla każdej klasy, które chcesz zostać rozszeregować. Takie konstruktory są znane jako "no-arg", "0-argument" lub (formalnie) nullary constructor.

W przeciwnym razie struktura nie może utworzyć instancji klasy.

+1

Dzięki @Timores. Wygenerowałem puste konstruktory dla każdej klasy i teraz to działa. –

+0

Dzięki @Timores! Wystąpił problem z jedną z moich klas obiektów danych (dokładnie klasa root). Konstruktor miał ustawiony jako prywatny, ponieważ używałem statycznej metody "loadFromXml" w tej samej klasie, aby utworzyć instancję obiektu. Krótko mówiąc: ** potrzebujesz ** albo publiczny konstruktor No-Arg albo publiczny konstruktor z adnotacjami (patrz bezpośredni komentarz Bourque'a do pytania), aby program poprawnie zserializował źródło XML. – Igor

+0

@BasilBourque Otrzymuję ten błąd podczas uruchamiania proguard na mojej aplikacji. Czy możesz rzucić okiem na [moje pytanie] (https://stackoverflow.com/q/47407587/1889768). – Abbas

-2

myślę, że lepiej jest użyć SAX do parsowania XML jest to przykład parsowania:

Musisz utworzyć klasę parsera takiego:

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

        } 

} 
} 

i jest przykładem dla wywołaj XML z adresu 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

Dzięki za pomoc @Yaz, ale problem jest teraz rozwiązany :) Nie próbowałem jeszcze SAX, ale spójrz na [Simple XML framework] (http://simple.sourceforge.net) i jestem pewien, że nie będziesz żal. Jest cicho proste. –

+0

@MohamedYaz Jak powiedział San Francesco, [SimpleFramework.org] (http: //simple.sourceforge.net /) jest naprawdę prosty do tego rodzaju pracy, serializując obiekty do XML. Jeden lub dwa wiersze kodu mogą wykonać całą pracę SAX, którą pokazujesz. –

+0

Czy wystarczy wskazać większą część kodu i wyjaśnić, co jest potrzebne, aby rozwiązać problem? – Phani

12

Nie musisz usuwać rzeczy z konstruktora. Można tylko dodać coś takiego:

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

on pracował dla mnie :)

+1

Po prostu uwaga tutaj, po adnotacji należy również dodać '(name =" ")' pasujące do nazwy zmiennej deserialized. – Falkenfighter

+0

To jest lepsza odpowiedź IMHO. Przeoczyłem to w dokumentacji Simple-Framework, ale właśnie to zalecają tutoriale. http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php#immutable Zobacz Injection konstruktora. –

+0

Pomogło mi to zrozumieć mój problem. Ale otrzymuję ten wyjątek dla konstruktora no/default. Jednak dodanie wszystkich elementów do konstruktora wydaje się rozwiązać problem. Mam jednak ogromną ilość kodu, aby móc to zrobić. Czy istnieje prostsze rozwiązanie? – Abbas

Powiązane problemy