2011-09-19 18 views
14

Tôi đang gặp sự cố khi deserialize tệp XML đã được tuần tự hóa thành công với khung công tác Simple XML Serialization (simpleframework.org).Ngoại lệ với việc đơn giản hóa khung công tác định dạng XML

an exception ném:

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

Đây là cuộc gọi:

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

ContactList.java My

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

Và đây là file XML Tôi đang cố gắng để deserialize.

<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, rất giống [ở đây] (http://stackoverflow.com/q/5894320/642706) và [ tại đây] (http://stackoverflow.com/q/16135304/642706) –

Trả lời

40

Không-Arg Constructor

Tôi không biết khuôn khổ XML đặc biệt này, nhưng, thông thường bạn cần một constructor mà mất không có tham số/lập luận cho mỗi lớp mà bạn muốn được deserialized. Các hàm tạo này được gọi là "no-arg", "0-argument", hoặc (chính thức) nullary constructor.

Nếu không, khung không thể khởi tạo lớp.

+1

Cảm ơn @Timores. Tôi tạo ra các hàm tạo rỗng cho mỗi lớp và bây giờ nó đang hoạt động. –

+0

Cảm ơn @Timores! Tôi đã có một vấn đề với một trong các lớp đối tượng dữ liệu của tôi (lớp gốc là chính xác). Hàm khởi tạo nó đã được đặt thành riêng tư, vì tôi đã sử dụng phương thức tĩnh "loadFromXml" trong cùng một lớp để khởi tạo một đối tượng. Câu chuyện dài ngắn: bạn ** cần ** hoặc là một hàm tạo No-Arg công khai hoặc một hàm tạo chú thích công khai (xem chú thích trực tiếp của Bourque đối với câu hỏi) để có chương trình deserialize nguồn XML đúng cách. – Igor

+0

@BasilBourque Tôi nhận được lỗi này khi chạy proguard trên ứng dụng của mình. Bạn có thể xem [câu hỏi của tôi] không (https://stackoverflow.com/q/47407587/1889768). – Abbas

-2

Tôi nghĩ rằng đó là tốt hơn để sử dụng SAX để phân tích cú pháp XML này là một ví dụ về phân tích cú pháp:

Bạn cần phải tạo một phân tích cú pháp lớp như thế này:

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

        } 

} 
} 

và đây là một ví dụ để gọi XML từ 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

Cảm ơn bạn đã trợ giúp @Yaz nhưng sự cố đã được giải quyết :) Tôi chưa thử SAX nhưng hãy xem qua [Simple XML framework] (http://simple.sourceforge.net) và tôi chắc chắn bạn sẽ không hối tiếc. Nó yên tĩnh đơn giản. –

+0

@MohamedYaz Như San Francesco đã nói, [SimpleFramework.org] (http: //simple.sourceforge.net /) thực sự là đơn giản cho loại công việc này, sắp xếp các đối tượng vào XML. Một hoặc hai dòng mã có thể thực hiện tất cả công việc SAX mà bạn hiển thị. –

+0

Bạn có thể chỉ trỏ phần chính của mã và giải thích cần thiết để giải quyết vấn đề không? – Phani

12

Bạn không phải xóa mọi thứ khỏi hàm tạo. Bạn chỉ có thể thêm một cái gì đó như thế này:

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

Nó được làm việc cho tôi :)

câu hỏi
+1

Chỉ cần lưu ý ở đây, sau khi chú thích, bạn cũng phải thêm '(name =" ")' khớp với tên của biến mà bạn đã được deserialized. – Falkenfighter

+0

Đây là câu trả lời hay hơn IMHO. Tôi đã bỏ qua điều này trong tài liệu Simple-Framework, nhưng đó là những gì các hướng dẫn cho bạn biết để làm. http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php#immutable Xem Constructor Injection. –

+0

Điều này đã giúp tôi hiểu vấn đề của mình. Nhưng tôi nhận được ngoại lệ này cho không có/constructor mặc định. Tuy nhiên việc thêm tất cả các phần tử vào hàm tạo dường như không giải quyết được vấn đề. Tuy nhiên tôi có một số lượng mã rất lớn để trải qua nếu tôi muốn hoàn thành nó. Có một giải pháp đơn giản hơn cho điều đó không? – Abbas

Các vấn đề liên quan