2016-08-05 66 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方法,我的解决方案有效,我会给你一个例子... –

相关问题