2011-03-27 27 views
8

Tôi đang sử dụng xStream để thao tác XML. Tất cả đều ổn. Để đưa vào kho lưu trữ XML và những thứ khác. Nhưng, tôi gặp sự cố:vấn đề xStream - Làm thế nào để deserialize nhiều đối tượng

Ví dụ: xml của tôi chứa thẻ và bên trong thẻ này, tôi có thêm một số thẻ có tên là <comment>. Xem mã ví dụ:

<comments> 
    <comment> 
     <id>1</id> 
     <desc>A comment</desc> 
    </comment> 
    <comment> 
     <id>2</id> 
     <desc>Another comment</desc> 
    </comment> 
    <comment> 
     <id>3</id> 
     <desc>Another one comment</desc> 
    </comment> 
</comments> 

Và tiến bộ. Tôi có thể tạo 500 thẻ bên trong thẻ. Và những nhận xét này thuộc loại nhận xét.

Tôi có thể làm như thế nào để tuần tự hóa với xStream để đặt tất cả các thẻ này trong các lớp học? Tôi không làm thế nào để thực hiện trong lớp học để nhận được các đối tượng khác nhau.

Rõ ràng, tôi sẽ làm điều này với một mảng hoặc một số khác. Nhưng tôi không biết làm thế nào tôi có thể làm điều này.

+2

vẻ xml của bạn một chút. Thẻ '' phải kết thúc bằng thẻ '' và không phải thẻ ''. Ngoài ra, đây là những gì bạn đang tìm kiếm: http://stackoverflow.com/questions/3136234/xstream-root-as-a-collection-of-objects? – Nishan

+0

[Câu hỏi này] (http://stackoverflow.com/questions/3824362/xstream-alias-of-list-root-elements) cũng tương tự. –

Trả lời

12

Đối với XML đó, bạn sẽ có thể được xem xét để có một cấu trúc lớp như:

public class Comment { 
    long id 
    String desc 
} 

public class Comments { 
    List<Comment> comments = new ArrayList<Comment>(); 
} 

Logic unmarshalling của bạn sau đó sẽ được cái gì đó như:

XStream xstream = new XStream(); 
xstream.alias("comments", Comments.class); 
xstream.alias("comment", Comment.class); 
xstream.addImplicitCollection(Comments.class, "comments"); 
Comments comments = (Comments)xstream.fromXML(xml); 

Additionaly, như đã đề cập trong Nishan các nhận xét, XML của bạn không được định dạng chính xác. Bạn cần đảm bảo rằng số điện thoại <comment> của mình kết thúc bằng </comment> chứ không phải </comments>. Bạn sẽ cần sửa lỗi này trước khi bất kỳ mã nào trong câu trả lời này sẽ hoạt động.

+0

Ooh, vâng. Cảm ơn bạn. Trong xml mà tôi đăng ở đây tôi đơn giản làm cho nó bằng tay. Xml là chính xác. Tất cả các thẻ đều đóng các thẻ chính xác. Cảm ơn về câu trả lời. –

+0

@Rob Hruska Tôi biết là hơi muộn, nhưng làm cách nào để chỉ định vị trí tệp XML? – Twhite1195

+0

@ Twhite1195 XML nên được đọc từ một FileInputStream hoặc một cái gì đó. –

1

Nếu bạn xử lý nhiều đối tượng, bạn có thể mong đợi gọi fromXML (InputStream in) nhiều lần để nhận từng đối tượng. Tuy nhiên, phương thức này không xử lý như mong đợi và đã ném một thông báo ngoại lệ có từ kém nếu bạn làm điều này. Ngoài ra, việc gói tất cả các đối tượng trong một đối tượng lớn hơn có thể khiến chương trình sử dụng nhiều bộ nhớ hơn nếu muốn hoặc hết bộ nhớ.

Để khắc phục điều này, tôi đã thực hiện một phương pháp tiện ích chung để tôi có thể phân tích từng đối tượng nhỏ thành chuỗi riêng để tôi có thể phương pháp fromXML(String) và vẫn tăng kích thước.

Ví dụ gọi:

String element = next(in, "</MyObject>"); 
MyObject o = (MyObject)xstream.fromXML(element); 

public static String next(InputStream in, String occurence) throws IOException { 
     StringBuffer sb = new StringBuffer(); 
     int i; 
     int pos = 0; 
     while((i = in.read()) != -1) { 
      sb.append((char)i); 
      if(i == occurence.charAt(pos)) { 
       pos ++; 
      } else 
       pos = 0; 

      if(pos == occurence.length()) 
       return sb.toString(); 
     } 
     return null; 
    } 
7

Mặc dù nó là một chủ đề cũ, nhưng đây là phiên bản chú thích:

@XStreamAlias("comment") 
public class Comment { 
    long id 
    String desc 
} 

@XStreamAlias("comments") 
public class Comments { 
    @XStreamImplicit(itemFieldName = "comment") 
    List<Comment> comments; 
} 

Để unmarshal bạn cần điều này:

XStream xStream = new XStream(); 
xStream.processAnnotations(new Class[] { Comments.class, Comment.class }); 
Comments comments = (Comments)xStream.fromXML(xml); 
Các vấn đề liên quan