如何编写我的模式,以便按顺序将元素映射到单独的属性而不是JAXB生成的类中的一个List <object>?</object>

时间:2014-08-13 15:14:34

标签: java xml jaxb xsd xjc

我的.xsd文件中有以下类型:

<complexType name='FooType' mixed='true'>
  <sequence>
    <element name='Bar' minOccurs='0' type='xenc:BarType'/>
    <element name='Baz' minOccurs='0' type='base64Binary'/>
    <any namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
  </sequence>
  <attribute name='Moo' type='anyURI' use='required'/>
</complexType>

<simpleType name='BarType'>
  <restriction base="integer"/>
</simpleType>

... JAXB XJC在FooType类中生成以下内容:

@XmlElementRefs({
    @XmlElementRef(name = "Bar", namespace = "http://namespace.blargh", type = JAXBElement.class),
    @XmlElementRef(name = "Baz", namespace = "http://namespace.blargh", type = JAXBElement.class)
})
@XmlMixed
@XmlAnyElement(lax = true)
protected List<Object> content;
@XmlAttribute(name = "Moo", required = true)
@XmlSchemaType(name = "anyURI")
protected String moo;

我需要访问Bar元素的值,但它在List<Object>中作为JAXBElement,我必须硬编码我的业务逻辑中的QName确保我有正确的事情。

如何修改架构以在生成的类中获取bar属性?生成新类的List<Integer>List<BarType>都可以使用。 (这并不理想,但如果我知道每个项目都是&#34; Bar&#34;元素并且只需处理该值,即使List<JAXBElement> bar也会有效。)

1 个答案:

答案 0 :(得分:4)

首先是:你真的需要mixed="true"吗?这意味着在FooType的所有子元素之间,您也可以拥有内容。这意味着您需要存储String的混合物(用于子元素之前,之间和之后的内容),一个Bar,一个Baz以及xs:any的任何内容。真的是一种混合物。

如果没有混合,xjc会生成:

public class FooType {
    @XmlElement(name = "Bar")
    protected BigInteger bar;
    @XmlElement(name = "Baz")
    protected byte[] baz;
    @XmlAnyElement(lax = true)
    protected List<Object> any;
    @XmlAttribute(name = "Moo", required = true)
    @XmlSchemaType(name = "anyURI")
    protected String moo;

(你真的需要BigInteger ??)

如果需要mixed="true",则必须测试QName值。如果List元素的类是不同的,你可能有一个很小的机会避免这种情况,但字符串将出现在文本子节点,Baz元素和稍后(“任何”)一切都可能发生。

不确定究竟是什么激发了这种XML Schema设计,但更好的替代方案并非不可思议。