在xsd中定义由xjc

时间:2016-04-21 13:27:31

标签: java xml xsd jaxb xjc

我们有一个xml文件,如下所示。请注意,我们的应用程序支持所有这三种情况:

<quantities>
  <quantity>8</quantity> <!-- case 1 -->
  <quantity></quantity>  <!-- case 2 -->
  <quantity/>            <!-- case 3 -->
</quantities>

我们现在正在为客户制作XML Schema,以帮助他们在将文件发送到我们的应用程序之前对其进行验证。

<xs:element name="quantity" type="xs:double"/>

但上面的XSD太简单了。对案例1来说,这是一个很好的验证,但它拒绝了案例2和案例。

因此,我们尝试使用自定义类型解决此问题。一种既可以是双重也可以是空字符串的类型。

<xs:simpleType name="double-or-empty">
  <xs:union memberTypes="xs:double">
    <xs:simpleType>
      <xs:restriction base="xs:string">
        <xs:enumeration value=""/>
      </xs:restriction>
    </xs:simpleType>
  </xs:union>
</xs:simpleType>

<xs:element name="quantity" type="double-or-empty"/>

从功能上来说,这显然是一种改进,但它有其缺点。当我们用java的xjc.exe工具生成我们的java类时。然后java将使用String来表示这些字段。哪个很烦人。我们实际希望的是(可空)java.lang.Double字段。

我们使用的主张:制作一个将此字段标记为nillable的xsd文件。

<xs:element name="quantity" type="xs:double" nillable="true"/>

我们了解到这仍然不支持案例2和3.这只是增加了一个案例:

<quantities>
  <quantity xs:nil="true"/>
</quantities>

多个来源表明使用 xs:nil可能会破坏互操作性。然后其他来源声称我们应该使用自定义属性,例如<quantity null="true"/>这些想法无论如何都是无用的,因为它们迫使我们改变我们长期使用的XML格式。

那么,有没有办法保留原始格式,并引导XJC工具在这里使用双打?

2 个答案:

答案 0 :(得分:0)

使用xs:union将空字符串约束与另一个约束(例如xs:double)结合使用:

  <xs:simpleType name="double-or-empty">
    <xs:union>
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:length value="0"/>
        </xs:restriction>
      </xs:simpleType>
      <xs:simpleType>
        <xs:restriction base="xs:double"/>
      </xs:simpleType>
    </xs:union>
  </xs:simpleType>

答案 1 :(得分:0)

总的来说,这看起来更像是XJC问题,而不是XSD问题。但是,如果实现解决方案的唯一方法是继续尝试在XSD中定义数据的不同方法,直到找到XJC更好处理的数据,那么您可以考虑:

  • 使用默认值声明quantity(假设<quantity/><quantity></quantity>映射到默认值而不是NULL或其逻辑等效值。

    < / LI>
  • 将数量类型声明为xs:double值列表,列表长度限制在0到1之间。 (可以使用pattern来定义约束,但我希望minLengthmaxLength方面在这里做得更好。)

  • 将数量类型声明为xs:double和除了字符串之外的某些类型的联合,它可以接受空值。我想我们在这里寻找一个基本类型,它似乎没有XJC有一个词法空间,它是xs:double的词法空间的超集。也许是xs:double和零长度字符串double的联合? (顺序是否对XJC很重要?看起来不是这样,因为你的声明将xs:double放在第一位,而kjhughes将空字符串放在第一位;但是为了以防万一,我会尝试撤销他的联合中的顺序。)

可能还有其他方式;这些是最容易想到的(在你和kjhughes已经尝试过之后)。