Reputation: 3669
I want to write XML Schema for XML file:
<root>
<rate>10</rate>
<rate></rate>
<rate>15</rate>
...
</root>
<rate> minOccurs is 1, maxOccurs is unbounded. <rate> must have xs:integer type, but what to do with <rate></rate>? I don't want to write <rate xsi:nil="true"/>.
Upvotes: 2
Views: 292
Reputation: 148977
I would write the XML schema as you intend it to be used. Since you will be using a C++ code generator this will make things much easier (I'm the EclipseLink JAXB (MOXy) lead, so I have experience with this on the Java side).
<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>
Since you anticipate receiving invalid data, you have the following options:
ValidationEventHandler
mechanism.Upvotes: 0
Reputation: 163262
An alternative to O.R.Mapper's approach is to declare the type of the element as a list of integers with 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>
I tend to prefer this approach to using a union of (integer, zero-length-string) as it's easier to handle in schema-aware XQuery and XSLT applications. It might also work better if you are using data binding using JAXB, I don't know.
Upvotes: 1
Reputation: 20710
Rather than one <rate>
element with an xs:integer
content, and another one without any content, you can only declare one <rate>
element that accepts any integer value or nothing as its contents.
Practically, this can be done with the <xs:union>
element:
<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>
This will accept <rate/>
, <rate></rate>
, <rate>42</rate>
(or any other xs:integer
value), but not <rate>Hello, World!</rate>
.
Note that for this to work, you must have set your prefix-less namespace in the schema to the same as your target namespace, or otherwise, emptyString
in the memberTypes
attribute will not be found. (Of course, you can instead also define a prefix for your target namespace and use that.)
I have omitted any explanations on how to write the complete schema and how to use maxOccurs
etc. because from your question I figure you already know how to do that. Please let me know if you need any further information on this.
Upvotes: 4