views:

35

answers:

1

I'm trying to construct a xsd scheme to validate a xml.
The xml is:

<payments>
  <pay3>5.1</pay3>
  <pay1>1</pay1>
  <pay2>50</pay2>
  <pay3>2</pay3>
</payments>

Tags <pay2>, <pay3> and <pay2> are optional and <pay1> is mandatory. All the <payX> tags may occur in any order and more than once or not to occur (except for <pay1>).

So far I made the following xsd types but it is not working correctly if <pay1> is not present:

<xs:simpleType name="TPayment">
    <xs:restriction base="xs:decimal">
      <xs:pattern value="[+]?\d+(\.\d{2})?" />
      <xs:minInclusive value="0" />
    </xs:restriction>
</xs:simpleType>
<xs:complexType name="TECR_Payments">
    <xs:choice minOccurs="1" maxOccurs="unbounded">
      <xs:element name="pay1" type="TPayment" maxOccurs="unbounded" />
      <xs:element name="pay2" type="TPayment" minOccurs="0" maxOccurs="unbounded" />
      <xs:element name="pay3" type="TPayment" minOccurs="0" maxOccurs="unbounded" />
      <xs:element name="pay4" type="TPayment" minOccurs="0" maxOccurs="unbounded" />
    </xs:choice>
</xs:complexType>

How to set that <pay1> is mandatory?

+1  A: 

Use this for your TECR_Payments type:

<xs:complexType name="TECR_Payments">
  <xs:sequence>
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element name="pay2" type="TPayment" />
      <xs:element name="pay3" type="TPayment" />
      <xs:element name="pay4" type="TPayment" />  
    </xs:choice>
    <xs:element name="pay1" type="TPayment" />
    <xs:choice minOccurs="0" maxOccurs="unbounded">
      <xs:element name="pay1" type="TPayment" />
      <xs:element name="pay2" type="TPayment" />
      <xs:element name="pay3" type="TPayment" />
      <xs:element name="pay4" type="TPayment" />
    </xs:choice>
  </xs:sequence>
</xs:complexType>

This allows any number (including zero) of <pay2>, <pay3>, or <pay4> elements in any order, then requires one <pay1>, and then allows any number of <payX> elements in any order.

Note that specifying minOccurs or maxOccurs on an xs:element inside an xs:choice doesn't really have the effect you want: The choice is first made between the type of element, and then the choice is made about how many elements of that type to use.

Joren