【问题标题】:Exception with Simple XML framework deserialization简单 XML 框架反序列化的异常
【发布时间】:2011-11-20 05:21:07
【问题描述】:

我在反序列化已使用Simple XML Serialization 框架 (simpleframework.org) 成功序列化的 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

我的联系人列表.java

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

我的笔记.java

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

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

    public String getNote() {
        return note;
    }
}

我的联系人.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>nicolas.sarkozy@elysee.fr</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>

【问题讨论】:

  • 仅供参考,非常相似的问题herehere

标签: java android xml-serialization


【解决方案1】:

无参数构造函数

我不知道这个特定的 XML 框架,但是,通常您需要一个不为您希望反序列化的每个类提供参数/参数的构造函数。此类构造函数称为“无参数”、“0 参数”或(正式)nullary constructor

否则,框架无法实例化该类。

【讨论】:

  • 谢谢@Timores。我为每个类生成了空的构造函数,它现在可以工作了。
  • 谢谢@Timores!我的一个数据对象类(确切地说是根类)有问题。它的构造函数被设置为私有,因为我在同一个类中使用静态方法“loadFromXml”来实例化一个对象。长话短说:您需要一个公共 No-Arg 构造函数或一个公共带注释的构造函数(参见 Bourque 对问题的直接评论),以便让程序正确反序列化 XML 源。
  • @BasilBourque 在我的应用程序上运行 proguard 时出现此错误。你能看看my question
【解决方案2】:

你不必从构造函数中删除东西。您可以添加如下内容:

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

它对我有用:)

【讨论】:

  • 这里只是说明一下,注解后还必须加上(name= "")与你反序列化的变量名相匹配。
  • 恕我直言,这是更好的答案。我在 Simple-Framework 文档中忽略了这一点,但这是教程告诉你要做的。 simple.sourceforge.net/download/stream/doc/tutorial/… 见构造函数注入。
  • 这帮助我理解了我的问题。但是对于无/默认构造函数,我得到了这个异常。然而,将所有元素添加到构造函数似乎确实解决了这个问题。但是,如果我想完成它,我需要处理大量代码。有没有更简单的解决方案?
【解决方案3】:

我认为使用 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());
        }

【讨论】:

  • 感谢@Yaz 的帮助,但问题现在已经解决了 :) 我还没有尝试过 SAX,但请看一下 Simple XML framework,我相信你不会后悔的。很简单。
  • @MohamedYaz 正如 San Francesco 所说,SimpleFramework.org 对于这种工作来说真的很简单,将对象序列化为 XML。一两行代码就可以完成您展示的所有 SAX 工作。
  • 你能指出代码的主要部分并解释解决问题所需的吗?
猜你喜欢
  • 1970-01-01
  • 2020-03-13
  • 2010-12-27
  • 1970-01-01
  • 2020-07-10
  • 1970-01-01
  • 1970-01-01
  • 2013-07-04
  • 1970-01-01
相关资源
最近更新 更多