我们有一个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工具在这里使用双打?
答案 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或其逻辑等效值。
将数量类型声明为xs:double值列表,列表长度限制在0到1之间。 (可以使用pattern
来定义约束,但我希望minLength
和maxLength
方面在这里做得更好。)
将数量类型声明为xs:double和除了字符串之外的某些类型的联合,它可以接受空值。我想我们在这里寻找一个基本类型,它似乎没有XJC有一个词法空间,它是xs:double的词法空间的超集。也许是xs:double和零长度字符串double的联合? (顺序是否对XJC很重要?看起来不是这样,因为你的声明将xs:double放在第一位,而kjhughes将空字符串放在第一位;但是为了以防万一,我会尝试撤销他的联合中的顺序。)
可能还有其他方式;这些是最容易想到的(在你和kjhughes已经尝试过之后)。