2012-07-12 48 views
8

現狀如何使用JAXB與容器相同的元件具有相似結構

我使用莫西的JAXB實現與他們的模式有很多similiar複雜類型大型XML文檔的工作,以避免重複代碼。具體地,存在充當具有以下結構列表包裝元素大約兩打類型:

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

對於每個這些列表的包裝器類元件,名稱改變和列表元素被包含變化。但是,屬性(全部是可選的)和單個EXTENSION元素(也是可選的)始終存在。這裏有兩種類型的應用的一個例子:

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

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

問題

我想,以避免重複代碼,因爲這些元素之間改變的僅僅是名稱和一個 - 或 - 它包含更多元素。做這個的最好方式是什麼?

我只能看到兩個可能的解決方案。

創建使用泛型以指示對象類型的一個具體類,以改變所述集合中的使用。然後使用MOXy的外部OX映射來指示應該如何序列化該類的任何單獨使用。喜歡的東西:

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

雖然我喜歡這個選項,就不會出現有可能重新定義在每個使用的基礎類的OX映射。

創建基礎類而不列表屬性,然後生成用於每個定製的包裝元件中的一個具體類。這個解決方案絕對有效,但我最終會得到大約二十個接近標識的類。

要麼#1可能還是有更好的方式來處理這個問題,我沒有想到的?

在此先感謝!

回答

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

} 

,並讀取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; 
    } 

不過是重複代碼真的重要嗎?如果您的模式具有列表容器類型的公共擴展基礎,並且您使用的是xjc,爲什麼要避免使用不同的類?畢竟JAXB背後的想法是每個獨特的複雜類型都有一個值類。

如果能夠制定一個處理類似,但不同的XML類型和不想要的大量的Java類,你可以切換到StAX的通用邏輯。

+0

的例子並不真正適合我要找的,除非我失去了一些東西。它不會真正讓我將列表元素綁定到JAXB註釋類,因爲解組器會將所有內容都轉換爲org.w3c.dom.Element對象。換一種方式會少一些尷尬,但沒有類型安全。 – Terence 2012-07-30 17:08:20

+0

對於你關於代碼重複的問題,你是對的,這不是非常重要。我真的很討厭這樣做。我最終走上了擁有30多個幾乎完全相同的課程的路線,儘管我對此並不欣喜。理想情況是創建我自己的具有泛型支持的自定義java.util.Collection類,但在這一點上似乎是不可能的。 – Terence 2012-07-30 17:12:21

相關問題