2011-09-19 50 views
14

我面臨一個問題,反序列化已成功序列化與Simple XML Serialization框架(simpleframework.org)的XML文件。異常與簡單的XML框架反序列化

還有就是an exception拋出:

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

這是呼叫:

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

我ContactList.java

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

我Note.java

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

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

    public String getNote() { 
     return note; 
    } 
} 

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

這是我嘗試反序列化的XML文件。

<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

僅供參考,非常類似的問題[這裏](http://stackoverflow.com/q/5894320/642706)和[這裏](http://stackoverflow.com/q/16135304/642706) –

回答

40

無參數的構造

我不知道這個特定的XML框架,但是,通常你需要一個構造函數不帶參數/參數爲每個要反序列化類。這樣的構造函數被稱爲「無參數」,「0參數」或(正式)nullary constructor

否則,框架無法實例化類。

+1

謝謝@Timores。我爲每個類生成了空的構造函數,現在它正在工作。 –

+0

謝謝@Timores!我遇到了一個我的數據對象類(準確的說是根類)的問題。它的構造函數被設置爲private,因爲我在同一個類中使用了一個靜態方法「loadFromXml」來實例化一個對象。長話短說:爲了讓程序正確地反序列化XML源代碼,您需要**公共No-Arg構造函數或公共註釋構造函數(請參閱Bourque對該問題的直接評論)。 – Igor

+0

@BasilBourque在我的應用程序上運行proguard時出現此錯誤。你可以看看[我的問題](https://stackoverflow.com/q/47407587/1889768)。 – Abbas

-2

我認爲這是更好地使用SAX解析的XML,這是分析的一個例子:

你需要創建一個類解析器是這樣的:

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

        } 

} 
} 

,這是一個例子,從URL調用XML:

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

感謝@ Yaz的幫助,但現在問題已解決:) 我還沒有嘗試過SAX,但只簡單看了一下[Simple XML framework](http://simple.sourceforge.net),我敢肯定,後悔。這很簡單。 –

+0

@MohamedYaz正如聖弗朗西斯科說的,[SimpleFramework.org](http://simple.sourceforge。net /)對於這類工作確實很簡單,即將對象序列化爲XML。一行或兩行代碼可以完成您展示的所有SAX工作。 –

+0

你能指出代碼的主要部分,並解釋需要解決這個問題嗎? – Phani

12

您不必從構造函數中刪除東西。你可以只添加這樣的事情:

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

它是爲我工作:)

+1

這裏只需要注意一下,在註釋之後,您還必須添加匹配您反序列化的變量名稱的'(name =「」)'。 – Falkenfighter

+0

這是更好的回答恕我直言。我在Simple-Framework文檔中忽略了這一點,但這正是教程告訴你要做的。 http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php#immutable請參閱構造函數注入。 –

+0

這幫助我瞭解我的問題。但是我得到這個例外是沒有/默認的構造函數。然而,將所有元素添加到構造函數似乎解決了這個問題。不過,如果我想完成這些工作,我的代碼量會很大。有更簡單的解決方案嗎? – Abbas