如何在复杂类型中重用注释?

时间:2010-11-02 14:57:12

标签: xml xsd jaxb

我正在尝试编写我的第一个xsd,它将从中生成JAXB映射的POJO,以便在Web服务中使用。我希望看到三个相关的类在xml中表示为......

<stringKey systemName="string key 1" businessName="Customer">Glorious strings</stringKey>
<numberKey systemName="number key 1" businessName="Invoice number">1025.52</numberKey>
<dateKey systemName="date key 1" businessName="Invoice date">1970-01-01</dateKey>

我正在尝试重用注释的声明,因此JAXB生成的POJO可以属于同一个接口。到目前为止,我有以下xsd ...

<xs:complexType name="dateKey">
    <xs:simpleContent>
        <xs:extension base="namedElement">
            <xs:attribute type="xs:dateTime" name="keyValue" />
        </xs:extension>
    </xs:simpleContent>
</xs:complexType>
<xs:complexType name="namedElement" abstract="true">
    <xs:simpleContent>
        <xs:extension base="xs:string">
            <xs:attribute type="xs:string" name="businessName" />
            <xs:attribute type="xs:string" name="systemName" />
        </xs:extension>
    </xs:simpleContent>
</xs:complexType>

这让我分道扬,,它给了我xml像......

<dateKey systemName="date key 1" businessName="Invoice date"><keyValue>1970-01-01</keyValue></dateKey>

我无法重用声明注释的类型,同时覆盖该类型的基础。 (注意我试图摆脱上面例子中的'keyValue'元素)。有什么想法吗?

编辑:我注意到xsd片段没有验证以下xml片段 - 这似乎在重构中丢失了,但我希望你明白这一点......

2 个答案:

答案 0 :(得分:1)

我发现你可以使用'attributeGroup'来提取常用属性来创建xsd之类的...

<xs:complexType name="dateKey">
    <xs:simpleContent>
        <xs:extension base="xs:dateTime">
            <xs:attributeGroup ref="namedElement" />
        </xs:extension>
    </xs:simpleContent>
</xs:complexType>
<xs:attributeGroup name="namedElement">
    <xs:attribute type="xs:string" name="businessName" />
    <xs:attribute type="xs:string" name="systemName" />
</xs:attributeGroup>

这允许我在类似元素之间重用属性,但生成的POJO不共享一个共同的抽象超类。我想我会停止自动生成POJO并使用手工制作的XSD和POJO,虽然我有点担心两者之间存在差异。

答案 1 :(得分:0)

为什么不从Java类开始并执行以下操作。您需要标记父类@XmlTransient才能使事情正常工作:

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlTransient;

@XmlTransient
public class NamedElement {

    private String businessName;
    private String systemName;

    @XmlAttribute
    public String getBusinessName() {
        return businessName;
    }

    public void setBusinessName(String businessName) {
        this.businessName = businessName;
    }

    @XmlAttribute
    public String getSystemName() {
        return systemName;
    }

    public void setSystemName(String systemName) {
        this.systemName = systemName;
    }

}

子类如下所示:

import java.util.Date;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlValue;

@XmlRootElement
public class DateKey extends NamedElement {

    private Date value;

    @XmlValue
    @XmlSchemaType(name="date")
    public Date getValue() {
        return value;
    }

    public void setValue(Date value) {
        this.value = value;
    }

}

然后是以下代码:

import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(DateKey.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        DateKey dateKey = (DateKey) unmarshaller.unmarshal(new File("input.xml"));

        Marshaller marshaller = jc.createMarshaller();
        marshaller.marshal(dateKey, System.out);
    }

}

将处理您的文件:

<dateKey systemName="date key 1" businessName="Invoice date">1970-01-01</dateKey>