我想为 XML 文件编写 XML Schema:
<root>
<rate>10</rate>
<rate></rate>
<rate>15</rate>
...
</root>
<rate> minOccurs 为 1,maxOccurs 无界。<rate> 必须有 xs:integer 类型,但是 <rate></rate> 怎么办?我不想写 <rate xsi:nil="true"/>。
您只能声明一个接受任何整数值或不接受任何内容作为其内容的元素,而不是一个<rate>
元素有内容,而另一个元素没有任何内容。xs:integer
<rate>
实际上,这可以通过以下<xs:union>
元素来完成:
<xs:simpleType name="emptyString">
<xs:restriction base="xs:string">
<xs:maxLength value="0"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="rate">
<xs:simpleType>
<xs:union memberTypes="xs:integer emptyString"/>
</xs:simpleType>
</xs:element>
这将接受<rate/>
, <rate></rate>
, <rate>42</rate>
(或任何其他xs:integer
值),但不接受<rate>Hello, World!</rate>
。
请注意,要使其正常工作,您必须已将架构中的无前缀命名空间设置为与目标命名空间相同,否则将无法emptyString
在属性中找到。memberTypes
(当然,您也可以为目标命名空间定义一个前缀并使用它。)
我省略了有关如何编写完整架构以及如何使用maxOccurs
等的任何解释,因为从您的问题中我认为您已经知道如何做到这一点。如果您需要任何关于此的更多信息,请告诉我。
ORMapper 方法的替代方法是将元素的类型声明为 maxLength=1 的整数列表。
<xs:element name="rate">
<xs:simpleType>
<xs:restriction base="listOfInteger">
<xs:maxLength value="1"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:simpleType name="listOfInteger">
<xs:list itemType="xs:integer"/>
</xs:simpleType>
我倾向于使用这种方法来使用(整数,零长度字符串)的并集,因为它在模式感知 XQuery 和 XSLT 应用程序中更容易处理。如果您使用 JAXB 使用数据绑定,它也可能会更好,我不知道。
我会按照您打算使用的方式编写 XML 模式。由于您将使用 C++ 代码生成器,这将使事情变得更容易(我是EclipseLink JAXB (MOXy)负责人,所以我在 Java 方面有这方面的经验)。
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="rate" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
由于您预计会收到无效数据,因此您有以下选择:
ValidationEventHandler
机制。