2010-09-10 43 views
50

Có lẽ một câu hỏi ngu ngốc: Tôi có một số List loại <Data> mà tôi muốn sắp xếp thành một tệp XML. Đây là lớp học của tôi Database chứa một ArrayList ...JAXB: Làm thế nào để sắp xếp các đối tượng trong danh sách?

@XmlRootElement 
public class Database 
{ 
    List<Data> records = new ArrayList<Data>(); 

    public List<Data> getRecords()     { return records; } 
    public void  setRecords(List<Data> records) { this.records = records; } 
} 

... và đây là lớp dữ liệu:

// @XmlRootElement 
public class Data 
{ 
    String name; 
    String address; 

    public String getName()   { return name;  } 
    public void setName(String name) { this.name = name; } 

    public String getAddress()    { return address;   } 
    public void setAddress(String address) { this.address = address; } 
} 

Sử dụng lớp thử nghiệm sau đây ...

public class Test 
{ 
    public static void main(String args[]) throws Exception 
    { 
     Data data1 = new Data(); 
      data1.setName("Peter"); 
      data1.setAddress("Cologne"); 

     Data data2 = new Data(); 
      data2.setName("Mary"); 
      data2.setAddress("Hamburg"); 

     Database database = new Database(); 
       database.getRecords().add(data1); 
       database.getRecords().add(data2); 

     JAXBContext context = JAXBContext.newInstance(Database.class); 
     Marshaller marshaller = context.createMarshaller(); 
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
        marshaller.marshal(database, new FileWriter("test.xml"));  
    } 
} 

. ..Tôi đã nhận được kết quả:

<database> 
    <records> 
     <address>Cologne</address> 
     <name>Peter</name> 
    </records> 
    <records> 
     <address>Hamburg</address> 
     <name>Mary</name> 
    </records> 
</database> 

Nhưng đó không phải là những gì tôi mong đợi, nghĩa là tất cả các thẻ cho các đối tượng <Data> bị thiếu. Tôi đang tìm kiếm một cách để xuất dữ liệu trong cấu trúc sau đây, nhưng tôi không biết làm thế nào để đạt được điều này:

<database> 
    <records> 
     <data> 
      <address>Cologne</address> 
      <name>Peter</name> 
     </data> 
     <data> 
      <address>Hamburg</address> 
      <name>Mary</name> 
     </data> 
    </records> 
</database> 

Một câu hỏi thêm: nếu tôi muốn để đối phó với vấn đề này mà không sử dụng @XmlElementWrapper@XmlElement chú thích, tôi có thể giới thiệu một lớp trung gian

public class Records 
{ 
    List<Data> data = new ArrayList<Data>(); 

    public List<Data> getData()    { return data; } 
    public void  setData(List<Data> data) { this.data = data; } 
} 

sử dụng bởi các lớp cơ sở sửa đổi

@XmlRootElement 
public class Database 
{ 
    Records records = new Records(); 

    public Records getRecords()    { return records; } 
    public void setRecords(Records records) { this.records = records; } 
} 

trong một chút thay đổi Test lớp:

... 
Database database = new Database(); 
database.getRecords().getData().add(data1); 
database.getRecords().getData().add(data2); 
... 

Kết quả cũng là:

<database> 
    <records> 
     <data> 
      <address>Cologne</address> 
      <name>Peter</name> 
     </data> 
     <data> 
      <address>Hamburg</address> 
      <name>Mary</name> 
     </data> 
    </records> 
</database> 

Đây có phải là sự khuyến cách để tạo ra một cấu trúc lớp Java theo cấu trúc file XML trên ?

+0

Tôi không thấy bạn sử dụng 'DataList' trong lớp thử nghiệm của bạn. – joschi

+0

Xin lỗi tôi - tôi đã sao chép và dán lớp sai ... Bây giờ nó đã được sửa chữa trong ví dụ trên. – rmv

Trả lời

89

Trên add sở hữu kỷ lục:

@XmlElementWrapper(name="records") 
@XmlElement(name="data") 

Để biết thêm thông tin về JAXB và bộ sưu tập các thuộc tính xem:

+1

Thật tuyệt, đúng vậy! Cảm ơn rất nhiều. – rmv

+1

Tôi phải thêm chú thích vào "getter" để làm việc này ... –

+2

@LawrenceTierney - Bài viết sau đây về '@ XmlAccessorType' có thể giúp chú thích các trường hoặc thuộc tính (getter/setter): http: // blog. bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html –

3

Đây là để đáp lại câu hỏi thứ hai của bạn disquised một trả lời:

Cả hai cách tiếp cận sẽ tạo cùng một XML. Đề xuất của tôi là đi với mô hình tốt nhất cho ứng dụng của bạn. Đối với tôi, thường sử dụng @ XmlElementWrapper/@ XmlElement. Vì "bản ghi" chỉ có ở đó để tổ chức các phần tử "dữ liệu", nó không thực sự xứng đáng với lớp riêng của nó.

tôi dẫn thi hành MOXy JAXB và chúng tôi cung cấp một phần mở rộng bản đồ XPath có trụ sở để đi xa hơn những gì có khả năng với @XmlElementWrapper:

+0

Nó thực sự khá ấn tượng những gì đang xảy ra trong lĩnh vực này. Tôi nghĩ rằng tôi cần một thời gian để liên lạc với kỹ thuật lập bản đồ mới này. Bạn có thể cho tôi một gợi ý đầu tiên, làm thế nào để đọc dữ liệu XML được xuất khẩu vào cấu trúc lớp một lần nữa? Nếu tôi sử dụng @ XmlElementWrapper/@ XmlElement để xuất, chương trình nhập khẩu than phiền rằng các lớp tương ứng là (rõ ràng :-) không tồn tại ... – rmv

+0

Việc nhập (unmarshal) chỉ hoạt động, bạn đang nhận được ngoại lệ nào? –

+1

Tôi nghĩ rằng tôi có một ngoại lệ mà lớp 'Records' không thể tìm thấy. Nhưng để chắc chắn, tôi sẽ xác minh nó bằng một ví dụ vào ngày mai ... – rmv

3

Để đối phó với thứ hai của bạn câu hỏi:

Is this the recommended way to create a Java class structure 
according to the XML file structure above? 

Về mặt kỹ thuật, việc giới thiệu thêm một lớp Records để giải quyết vấn đề JAXB của bạn là không cần thiết và công việc thừa, vì JAXB không cần nó. Tài sản @XmlElementWrapper@XmlElementname được thiết kế để giải quyết vấn đề của bạn.

Từ nhận xét của bạn đến câu trả lời của Blaise, tôi duy trì tutorial với các ví dụ hoạt động giải thích cách xử lý các lớp chung như Danh sách, v.v. khi không sửa đổi.

+0

Trang web hướng dẫn tuyệt vời! – rmv

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