2010-11-10 36 views
36

Tôi đang cố gắng sắp xếp một danh sách các đối tượng đang triển khai một giao diện chung. Có 3 lớp và 1 giao diện liên quan đến:Lập danh sách các đối tượng thực hiện một giao diện chung, với JaxB

Cộng đồng lớp (có một phương pháp: Danh sách <Person> getPeople();)

Person giao diện (có một phương pháp: Chuỗi getName();)

Girl lớp (thực hiện Person)

Boy lớp (thực hiện Người)

Xem mã bên dưới.

Tôi muốn một XML mà trông giống như sau:

<community> 
    <people> 
    <girl> 
     <name>Jane</name> 
    </girl> 
    <boy> 
     <name>John</name> 
    </boy> 
    <girl> 
     <name>Jane</name> 
    </girl> 
    <boy> 
     <name>John</name> 
    </boy> 
    </people> 
</community> 

hoặc có thể là:

<community> 
    <people> 
    <person> 
     <girl> 
     <name>Jane</name> 
     </girl> 
    </person> 
    <person> 
     <boy> 
     <name>John</name> 
     </boy> 
    </person> 
    </people> 
</community> 

Cho đến nay những gì tôi nhận được là:

<community> 
    <people> 
     <person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="girl"> 
      <name>Jane</name> 
     </person> 
     <person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="boy"> 
      <name>John</name> 
     </person> 
     <person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="girl"> 
      <name>Jane</name> 
     </person> 
     <person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="boy"> 
      <name>John</name> 
     </person> 
    </people> 
</community> 

Tôi nhận ra tôi có thể thay đổi phần tử thành phần tử khác, nhưng tôi muốn tên phần tử là tên được spesified trong lớp Girl hoặc Boy.

Việc này có thể thực hiện được không? Cảm ơn.

@XmlRootElement(name = "community") 
public class Community { 

private List<Person> people; 

@XmlElementWrapper 
@XmlElement(name="person") 
public List<Person> getPeople() { 
    return people; 
} 

public Community() { 
    people = new ArrayList<Person>(); 
    people.add(new Girl()); 
    people.add(new Boy()); 
    people.add(new Girl()); 
    people.add(new Boy()); 
} 
} 







@XmlRootElement(name = "girl") 
public class Girl implements Person { 

@XmlElement 
public String getName() { 
    return "Jane"; 
} 
} 


@XmlRootElement(name = "boy") 
public class Boy implements Person { 

@XmlElement 
public String getName() { 
    return "John"; 
} 
} 



@XmlJavaTypeAdapter(AnyTypeAdapter.class) 
public interface Person { 
public String getName(); 
} 



public class AnyTypeAdapter extends XmlAdapter<Object, Object> { 

@Override 
    public Object marshal(Object v) throws Exception { 
    return v; 
    } 

@Override 
    public Object unmarshal(Object v) throws Exception { 
    return v; 
    } 

} 

Trả lời

44

Đối với kịch bản này, tôi muốn giới thiệu việc sử dụng @XmlElements. @XmlElements được sử dụng để đại diện cho khái niệm lược đồ XML của sự lựa chọn:

Sau đây là cách nó sẽ trông ví dụ của bạn:

@XmlElements({ 
    @XmlElement(name="girl", type=Girl.class), 
    @XmlElement(name="boy", type=Boy.class) 
}) 
@XmlElementWrapper 
public List<Person> getPeople() { 
    return people; 
} 

@XmlElementRef tương ứng với các khái niệm về các nhóm thay thế trong lược đồ XML. Đây là lý do tại sao câu trả lời trước đó yêu cầu người được thay đổi từ một giao diện cho một lớp.

12

OK, nếu bạn chuẩn bị thay đổi Người từ giao diện thành lớp cơ sở trừu tượng thì bạn vàng. Đây là mã:

public class Main { 


    public static void main(String[] args) throws Exception { 

    Community community = new Community(); 

    JAXBContext context = JAXBContext.newInstance(Community.class); 
    Marshaller marshaller = context.createMarshaller(); 
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
    marshaller.marshal(community, System.out); 

    } 
} 

@XmlRootElement(name = "community") 
@XmlSeeAlso({Person.class}) 
public class Community { 

private List<Person> people; 

@XmlElementWrapper(name="people") 
@XmlElementRef() 
public List<Person> getPeople() { 
    return people; 
} 

public Community() { 
    people = new ArrayList<Person>(); 
    people.add(new Girl()); 
    people.add(new Boy()); 
    people.add(new Girl()); 
    people.add(new Boy()); 
} 
} 

@XmlRootElement(name="boy") 
public class Boy extends Person { 

public String getName() { 
    return "John"; 
} 
} 

@XmlRootElement(name="girl") 
public class Girl extends Person { 

public String getName() { 
    return "Jane"; 
} 
} 

@XmlRootElement(name = "person") 
@XmlSeeAlso({Girl.class,Boy.class}) 
public abstract class Person { 

    @XmlElement(name="name") 
public abstract String getName(); 
} 

Bí quyết chính là sử dụng @XmlElementRef trong Danh sách cộng đồng. Điều này xác định loại của lớp thông qua đó là @XmlRootElement. Bạn cũng có thể quan tâm đến số @XmlSeeAlso giúp tổ chức khai báo ngữ cảnh.

Và đầu ra là

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<community> 
    <people> 
     <girl> 
      <name>Jane</name> 
     </girl> 
     <boy> 
      <name>John</name> 
     </boy> 
     <girl> 
      <name>Jane</name> 
     </girl> 
     <boy> 
      <name>John</name> 
     </boy> 
    </people> 
</community> 
Các vấn đề liên quan