2012-07-12 32 views
8

Tình hìnhLàm thế nào để tránh trùng lặp mã sử dụng JAXB với các yếu tố chứa giống như với một cấu trúc tương tự

Tôi đang sử dụng thực hiện JAXB MOXY để làm việc với một tài liệu XML lớn có schema có nhiều loại phức tạp tương tự. Cụ thể, có khoảng hai chục loại hoạt động như các phần tử trình bao bọc danh sách với cấu trúc sau:

<ITEMS attr1="X" attr2="Y"> 
    <ITEM>...</ITEM> 
    ... 
    <EXTENSION/> 
<ITEMS> 

Đối với mỗi phần tử danh sách giống như bọc này, thay đổi tên và phần tử danh sách có chứa thay đổi. Tuy nhiên, các thuộc tính (tất cả đều là tùy chọn) và phần tử EXTENSION đơn (cũng là tùy chọn) luôn có mặt. Dưới đây là một ví dụ về sử dụng của hai trong số các loại:

<ROLES visible="false"> 
    <ROLE type="X"/> 
    <ROLE type="Y"/> 
</ROLES> 

<PAYMENTS visible="true"> 
    <PAYMENT> 
    <PAYEENAME>Joe</PAYEENAME> 
    </PAYMENT> 
    <EXTENSION> 
    <SOMETHING>Here</SOMETHING> 
    </EXTENSION> 
</PAYMENTS> 

Các Câu hỏi

Tôi muốn tránh trùng lắp mã kể từ khi điều duy nhất thay đổi giữa các yếu tố này là tên và một hay- nhiều phần tử hơn. Cách tốt nhất để làm việc này là gì?

Tôi chỉ có thể thấy hai giải pháp khả thi.

Tạo một lớp bê tông sử dụng Generics để chỉ các loại đối tượng được sử dụng trong bộ sưu tập mà thay đổi. Sau đó, sử dụng ánh xạ OX bên ngoài của MOXy để cho biết cách sử dụng từng cá nhân của lớp nên được tuần tự hóa. Một cái gì đó như:

public class GenericContainer<T> { 
@XmlAttribute 
protected Boolean visibile; 
@XmlElement(name = "Extension") 
protected Extension extension; 

// OX Mappings done in external meta file 
protected List<T> items; 
... 
} 

Mặc dù tôi thích tùy chọn này, dường như không thể xác định lại ánh xạ OX của lớp trên cơ sở mỗi lần sử dụng.

Tạo một lớp cơ sở mà không có sự Danh sách bất động sản, và sau đó tạo ra một lớp bê tông cho mỗi phần tử tùy chỉnh wrapper. Giải pháp này chắc chắn hoạt động, nhưng tôi sẽ kết thúc với khoảng hai chục lớp học gần giống nhau.

Hoặc là # 1 có thể hoặc có cách nào tốt hơn để xử lý việc này mà tôi chưa từng nghĩ đến?

Cảm ơn trước!

Trả lời

0
public class GenericContainer { 

private Boolean visible; 
private Object extension; 
private List<Object> nodes; 

@XmlAttribute 
public Boolean isVisible() { 
    return visible; 
} 

public void setVisible(Boolean visible) { 
    this.visible = visible; 
} 

@XmlElement(name="EXTENSION") 
public Object getExtension() { 
    return extension; 
} 

public void setExtension(Object extension) { 
    this.extension = extension; 
} 

@XmlAnyElement 
public List<Object> getNodes() { 
    return nodes; 
} 

public void setNodes(List<Object> nodes) { 
    this.nodes = nodes; 
} 

} 

Và để đọc XML

JAXBContext jaxbContext = JAXBContext.newInstance("jaxbtest1"); 
    Unmarshaller um = jaxbContext.createUnmarshaller(); 

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder db = dbf.newDocumentBuilder(); 
    Document doc = db.parse(new File("src/test1.xml")); 
    Node node = doc.getFirstChild(); 

    JAXBElement<GenericContainer> jaxbE = um.unmarshal(node, GenericContainer.class); 

    GenericContainer gc = jaxbE.getValue(); 
    Boolean vis = gc.isVisible(); 
    Element ext = (Element)gc.getExtension(); 
    for(Object o : gc.getNodes()) { 
     Element listItem = (Element)o; 
    } 

Nhưng là việc lặp lại code thực sự quan trọng? Nếu lược đồ của bạn có cơ sở mở rộng chung cho các loại vùng chứa danh sách và bạn đang sử dụng xjc tại sao lại tránh các lớp riêng biệt? Sau khi tất cả ý tưởng đằng sau JAXB có một lớp giá trị cho mỗi loại phức tạp duy nhất.

Nếu bạn có thể tạo logic mục đích chung xử lý các loại XML tương tự nhưng khác biệt và không muốn một số lượng lớn các lớp Java bạn có thể chuyển sang StAX.

+0

Ví dụ này không thực sự phù hợp với những gì tôi đang tìm kiếm, trừ khi tôi thiếu thứ gì đó. Nó sẽ không thực sự cho phép tôi liên kết các phần tử danh sách với các lớp được chú thích JAXB, vì unmarshaller sẽ biến mọi thứ thành các đối tượng org.w3c.dom.Element. Đi theo một cách khác sẽ có chút ít vụng về, nhưng không có sự an toàn kiểu nào. – Terence

+0

Đối với câu hỏi của bạn về sao chép mã, bạn nói đúng, điều đó không quan trọng lắm. Tôi thực sự ghét làm điều đó. Tôi đã đi xuống con đường có hơn 30 lớp giống hệt nhau, mặc dù tôi không ngây ngất về nó. Tình huống lý tưởng sẽ là tạo ra lớp java.util.Collection tùy chỉnh của riêng tôi với sự hỗ trợ Generics, nhưng điều đó dường như là không thể vào thời điểm này. – Terence

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