JAXB:使用xs:extension时忽略元素的顺序

时间:2012-10-23 04:04:44

标签: jaxb xsd jaxb2 xsd-validation

我们正在使用JAXB进行Java-xml绑定。我们最初创建了域类,然后使用 schemagen 命令行工具生成了以下模式。但生成的架构无效,给出以下错误消息。

错误消息: cos-all-limited.1.2:所有模型组必须出现在{min occurrence} = {max occurrence} = 1的粒子中,并且该粒子必须是构成复杂类型的{content type}的对的一部分定义

使用案例 有两个类Emp(基类)和Dept(子类)。
1.元素序列没有限制(表示empId,deptId和deptName可以按任何顺序出现)。所以我们用xs:all element
2.在Dept类中,deptId字段应该只出现一次(minOccurs = 1,maxOccurs = 1),deptName是可选的。
根据我的用例,我无法生成有效的架构。我在谷歌上搜索过。但我找不到解决方案。所以我期待专家可以回答这个问题。您能否请看下面的课程,架构并指导我正确的方向。

注意:请不要建议我创建一些临时域类。
感谢您的期待。

Emp.java

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name="EmpType", propOrder={})
@XmlRootElement
public class Emp {

    @XmlElement(name="empId", required = true)
    private String empId;
}

Dept.java

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name="DeptType", propOrder={})
public class Dept extends Emp
{

    @XmlElement(name="deptId", required = true)
    private String deptId;
    private String deptName;
}

Schema1.xsd

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="emp" type="EmpType"/>

  <xs:complexType name="EmpType">
    <xs:sequence>
      <xs:element name="empId" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="DeptType">
    <xs:complexContent>
      <xs:extension base="EmpType">
        <xs:all>  <!--showing error message, mentioned above -->
          <xs:element name="deptId" type="xs:string" minOccurs="1" maxOccurs="1"/>
          <xs:element name="deptName" type="xs:string" minOccurs="0"/>
        </xs:all>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
</xs:schema>

1 个答案:

答案 0 :(得分:1)

您尝试允许的文档结构实际上很难在XML架构中表示。您可能无法从JAXB (JSR-222)带注释的模型生成它。但是你有几个选择:

选项#1 - 生成更简单的XML架构

如果您没有使用XML架构验证XML内容,并且只是将其用作人们可以用作指南的文档,那么我会删除all部分并使用sequence代替。这将与您拥有的继承关系更好地工作。如果您未在Schema上指定Unmarshaller的实例,则不会强制执行元素的顺序,因此您将能够阅读符合规则的所有XML文档。

选项#2 - 创建自己的XML架构

如果您希望XML模式准确反映所有可能接受的输入,那么您需要自己编写。您可以使用包级别@XmlSchema注释来引用此现有XML架构。

@XmlSchema(location = "http://www.example.com/package/YourSchema.xsd")
package com.example;

import javax.xml.bind.annotation.XmlSchema;