Reputation: 7050
So with XML Schema restriction you can derive a new complex type which has a subset of elements of a parent type. For example, if I have this base type:
<complexType name="baseType">
<complexContent>
<restriction base="anyType">
<attribute name="number" type="decimal"/>
<attribute name="quantity" type="positiveInteger"/>
<sequence>
<element name="first" minOccurs="0" maxOccurs="1" type="string"/>
<element name="second" minOccurs="0" maxOccurs="1" type="string"/>
</sequence>
</restriction>
</complexContent>
</complexType>
And create the following new type:
<complexType name="newType">
<complexContent>
<restriction base="anyType">
<attribute name="number" type="decimal"/>
<sequence>
<element name="first" type="string"/>
</sequence>
</restriction>
</complexContent>
</complexType>
My question is which attributes and elements are allowed for new type? Only number
and first
? What are occurs limits on the first
element? Default (minOccurs="1" maxOccurs="1"
) or from the parent (minOccurs="0" maxOccurs="1"
)?
And if I have additional type:
<complexType name="newType2">
<complexContent>
<restriction base="anyType">
<sequence>
<element name="first" type="string"/>
</sequence>
</restriction>
</complexContent>
</complexType>
Which attributes are allowed here?
Upvotes: 3
Views: 1637
Reputation: 23637
In a restriction you must include all the elements and attributes, from the set declared in the base type, that you wish to allow in the new type. The element declarations in the restriction will override the previous ones.
Your schema is almost correct. Within a complexType
element, a sequence
must appear before an attribute
declaration. If you have this schema:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" targetNamespace="tns" xmlns:tns="tns">
<complexType name="baseType">
<complexContent>
<restriction base="anyType">
<sequence>
<element name="first" minOccurs="0" maxOccurs="1" type="string"/>
<element name="second" minOccurs="0" maxOccurs="1" type="string"/>
</sequence>
<attribute name="number" type="decimal"/>
<attribute name="quantity" type="positiveInteger"/>
</restriction>
</complexContent>
</complexType>
<complexType name="newType">
<complexContent>
<restriction base="tns:baseType"> <!-- restriction of baseType -->
<sequence>
<element name="first" type="string"/>
</sequence>
<!-- attribute declarations are not necessary, since they allow the same types -->
</restriction>
</complexContent>
</complexType>
<element name="root">
<complexType>
<choice maxOccurs="unbounded">
<element name="base" type="tns:baseType" minOccurs="0"/>
<element name="new" type="tns:newType" minOccurs="0"/>
</choice>
</complexType>
</element>
</schema>
It will validate the two first <base>
elements, but will fail validation in the two <new>
elements for the reasons explained in the comments:
<base number="123.5" quantity="3"> <!-- will validate -->
<first></first>
<second></second>
</base>
<base> <!-- will validate: min occurs for <first> and <second> is zero OK -->
</base>
<new number="123.5"> <!-- will fail validation: min occurs of <first> is one -->
</new>
<new number="123.5" quantity="3"> <!-- will validate: quantity attribute is inherited -->
<first></first>
<second></second> <!-- will fail validation: no <second> element allowed -->
</new>
The element and attribute declarations in the derived type must be equal or more restrictive: you can't have in the derived type:
<element name="first" minOccurs="0" maxOccurs="unbounded" type="string"/>
because in the base type there is no explicit maxOccurs
so the value is 1, and unbounded
wouldn't be a restriction. Also if you declare atributes as decimal
, for example, in the base type, you can declare it again as integer
to restrict it more, but you could not declare an attribute which originally was integer
as decimal
since that wouldn't be a restriction.
Upvotes: 2