2016-08-05 69 views
1

我有一個模式,即a schema for metalink file。爲此我想使用Maven Maven-jaxb2-plugin生成類。JAXB,如何爲具有元素重複屬性的模式生成類

該模式允許以屬性或元素的形式輸入版本,因此它具有重複的屬性。我如何使用Jaxb爲這樣的模式生成一個Java類(甚至是可能的),而不需要重命名屬性或元素。所以基本上我想這個重複的屬性映射到某種複雜類型與內部指示是否屬性或元素。至少這樣的解決方案會把我看作XML的最接近的表示。

可以這樣做嗎?如果是,那麼如何?

下面,說有問題的xsd片段。

<xs:complexType name="metalinkType"> 
    <xs:all> 
     <xs:element minOccurs="0" name="description" type="xs:string"/> 
     <xs:element minOccurs="0" name="identity" type="xs:string"/> 
     <xs:element minOccurs="0" name="license" type="licenseType"/> 
     <xs:element minOccurs="0" name="publisher" type="publisherType"/> 
     <xs:element minOccurs="0" name="releasedate" type="RFC822DateTime"/> 
     <xs:element minOccurs="0" name="tags" type="xs:string"/> 
     <xs:element minOccurs="0" name="version" type="xs:string"/> 
     <xs:element name="files" type="filesType"/> 
    </xs:all> 
    <xs:attribute name="version" type="xs:string" default="3.0"/> 
    <xs:attribute name="origin" type="xs:anyURI"/> 
    <xs:attribute name="type" default="static"> 
     <xs:simpleType> 
      <xs:restriction base="xs:string"> 
       <xs:enumeration value="dynamic"/> 
       <xs:enumeration value="static"/> 
      </xs:restriction> 
     </xs:simpleType> 
    </xs:attribute> 
    <xs:attribute name="pubdate" type="RFC822DateTime"/> 
    <xs:attribute name="refreshdate" type="RFC822DateTime"/> 
    <xs:attribute name="generator" type="xs:string"/> 
</xs:complexType> 

編輯

而對於這樣的模式,我想已經由JAXB生成的Java模型,如:

public class Metalink { 
    private PropertyType<String> version; 
    ... 
} 

public class PropertyType<T> { 
    private T val; 
    private boolean isAttribute; 
    ... 
} 

是否有可能實現這樣的事情或者是在Java模型中有兩個不同屬性的唯一解決方案?

+0

你可以使用'@ XmlJavaTypeAdapter'來創建一個你想要的結構,但你總是會以一個基於兩個屬性的Jaxb Java模型結束....我建議採取我的方法。 –

回答

0

是的,可以通過JAXB Binding Customization完成。

這是一個小的XSD我,以滿足您的問題(一個屬性和元素之間的名稱衝突):

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://hello" 
    elementFormDefault="qualified" 
    xmlns:tns="http://hello" 
> 
    <xs:element name="metalink" type="tns:metalinkType" /> 
    <xs:complexType name="metalinkType"> 
     <xs:sequence> 
      <xs:element name="version" type="xs:string" minOccurs="1" /> 
     </xs:sequence> 
     <xs:attribute name="version" type="xs:string" use="required" /> 
    </xs:complexType> 
</xs:schema> 

當從日食執行JAXB代,我得到一個錯誤,如:

[ERROR] Property "Version" is already defined. Use <jaxb:property> to resolve this conflict 

但是,當我修改XSD一些定製的標籤,問題消失:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://hello" 
    elementFormDefault="qualified" 
    xmlns:tns="http://hello" 
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" <!-- ADDED --> 
    jaxb:version="1.0" <!-- ADDED --> 
> 
    <xs:element name="metalink" type="tns:metalinkType" /> 
    <xs:complexType name="metalinkType"> 
     <xs:sequence> 
      <xs:element name="version" type="xs:string" minOccurs="1" /> 
     </xs:sequence> 
     <xs:attribute name="version" type="xs:string" use="required" > 
      <xs:annotation> 
       <xs:appinfo> 
        <jaxb:property name="version2"/> <!-- ADDED! --> 
       </xs:appinfo> 
      </xs:annotation> 
     </xs:attribute> 
    </xs:complexType> 
</xs:schema> 

避免碰撞問題並允許生成關聯的類。

注:所呈現的例子假設你想要的(你可以)修改與內嵌自定義有問題的XSD ...根據文檔,你還可以在外部文件中定義自定義(您需要檢查和嘗試這個)。

this是另一個值得注意的鏈接...

希望這有助於!

** **更新:實例來實現你想要的Java模型。該示例假定您遵循之前描述的步驟......你會是這樣一類結尾:

// xml annotations 
public class MetalinkType { 
    ... 
    @XmlElement(name = "version) 
    private String version; 
    ... 
    @XmlAttribute(name = "version") 
    private String version2; 
    ... 
    public void setVersion(String version, boolean asElem) { 
     If (asElem) { 
      this.version = version; 
     } else { 
      this.version2 = version; 
     } 
    } 
    // individual setter as setVersion and setVersion2 are not exposed 
} 
+0

是的,這個解決方案會讓模式編譯,但這不是我期待的(希望)。我試圖實現的是在Java模型中只有一個屬性'version',只是以某種方式用info標記,如果它是xml元素或屬性的話。這就是爲什麼主要問題是可能的。 – MJar

+0

如果你能做到這一點,你如何設定這樣的標誌?通過一些setter方法? –

+0

如果通過setter方法,我的解決方案有效,我會給你一個例子... –

相關問題