johkar
johkar

Reputation: 321

XSD: Options for allowing null values when declaring xs:integer data types

My problem (or question) centers around empty elements which are typed as xs:integer. I need to allow for empty elements so I used a union to allow an empty element or a valid integer as the value as shown in the schema below. However, my schema serves a dual role and also needs to be imported into 3rd party software which expects data types of String, Float, Integer or Date. If I code the schema using the union method for all integers they will not be typed as integers in the software. Is there another way other than the union method of allowing an empty element for integer data types? I'd like to just have the one XSD but can have two if that is what needs to happen.

Given XML sample of:

<?xml version="1.0" encoding="UTF-8"?>
<company>
    <division>
        <department>
            <roles/>
            <employees>7</employees>
        </department>
    </division>
</company>

And schema of:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:simpleType name="nullval">
        <xs:union memberTypes="IntegerType empty"/>
    </xs:simpleType>
    <xs:simpleType name="IntegerType">
        <xs:restriction base="xs:integer"/>
    </xs:simpleType>
    <xs:simpleType name="empty">
        <xs:restriction base="xs:string">
            <xs:maxLength value="0"/>
        </xs:restriction>
    </xs:simpleType>
    <xs:element name="company">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="division">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="department" minOccurs="0" maxOccurs="unbounded">
                                <xs:complexType>
                                    <!-- elements may appear in any order -->
                                    <xs:all minOccurs="0" maxOccurs="1">
                                        <xs:element name="roles" type="nullval"/>
                                        <xs:element name="employees" type="xs:integer"/>
                                    </xs:all>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

Upvotes: 19

Views: 65061

Answers (4)

Ahmad Hindash
Ahmad Hindash

Reputation: 1629

What you have to do is to assign two restrictions on the same element, plus make a union of them such as in the following example:

<xs:element name='job_code'>
  <xs:simpleType>
    <xs:union>
      <xs:simpleType>
        <xs:restriction base='xs:string'>
          <xs:length value='0'/>
        </xs:restriction>
      </xs:simpleType>
      <xs:simpleType>
        <xs:restriction base='xs:integer'>
        </xs:restriction>
      </xs:simpleType>
    </xs:union>
  </xs:simpleType>
</xs:element>

Using this restriction, you tell the XML validation to allow any integer value and allowing the element if it is empty.

Upvotes: 16

Menol
Menol

Reputation: 1348

I had the same requirement today. Following XSD only allows empty, or any value between -1 and 999

I am extracting only the required stuff from a very large XSD so some of these might look like overkill.

<xs:simpleType name="emptyString">
    <xs:restriction base="xs:string">
    <xs:enumeration value=""/>
    </xs:restriction>
</xs:simpleType>


<xs:simpleType name="int-1999">
 <xs:restriction base="xs:int">
 <xs:minInclusive value="-1"/>
 <xs:maxInclusive value="999"/>
 </xs:restriction>
</xs:simpleType>


<xs:element name="preNotificationPeriod" nillable="true">
  <xs:simpleType>
  <xs:union memberTypes="int-1999 emptyString"/>
  </xs:simpleType>
</xs:element>

Reference - http://www.ilearnttoday.com/xsd-empty-values-and-range-restriction-for-numeric-types

More details on this article

Upvotes: 4

user2198825
user2198825

Reputation: 81

hi the nillable="true" and minOccurs="0" works only when you dont send the tag at all. If however you need to pass an empty value inside the tags i think you have to implement a union.

Upvotes: 8

sho222
sho222

Reputation: 722

Have you tried

<xs:element name="roles" type="xs:integer" nillable="true"/>

Upvotes: 17

Related Questions