2011-09-19 56 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