ComplexType restriction in xsd - xsd

I am creating a XSD and defining ComplexType and want to know how to create restriction.
For example,
<xsd:complexType name="MyTestType">
<xsd:sequence>
<xsd:element name="Country" type="xsd:string" >
...
And, I want the element "Country" to be allowed 1 to 10 characters long.
Is there a way I can use minLength and maxLength on the element?
Thanks.

The following code would do what you ask;
<xs:simpleType name="myTestType">
<xs:restriction base="xs:string">
<xs:pattern value="([a-z][A-Z])+"/>
<xs:minLength value="1"/>
<xs:maxLength value="10" />
</xs:restriction>
</xs:simpleType>
You could simplify it and write the following;
<xs:simpleType name="myTestType">
<xs:restriction base="xs:string">
<xs:pattern value="([a-z][A-Z]){1-10}"/>
</xs:restriction>
</xs:simpleType>

Related

XSD complexType with element AND simpleContent

Working with XML 1.1 in Oxygen XML Editor version 23.1.
Originally I wandted to make an xsd schema that can have a complexType-element with a child-element, an extension and a bunch of attributes. A first possible solution I was able to get here but figured out it didn't fit to my problem, because the child-element itself consists of several elements and attributes which makes the original approach invalid, causing the error message: "The content type of a derived type and that of its base must both be mixed or both be element-only. Type 'complexTypeContent' is mixed, but its base type is not".
To my problem itself: The aim is for the child-element random to only be used when the attribute until has the value 'random'. So in the end a XML-file like this should be valid:
<instruction>
<type repeat='1' until='random'><random start='1' end='6'/>Dice Roll</type>
</instruction>
Instead - if the attribute until has not the value "random" - the element random must not be allowed. So something like this should be forbidden:
<instruction>
<type repeat='1' until='2'><random start='1' end='6'/>Dice Roll</type>
</instruction>
With help from here I was able to modify my xsd-scheme to something like this. But as already stated, it doesn't compile without an error message:
<xs:element name="root">
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element name="instruction" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="type">
<xs:alternative test="#until = 'random'" type="complexTypeContent"/>
<xs:alternative type="simpleTypeContent"/>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="complexTypeContent" mixed="true">
<xs:complexContent>
<xs:extension base="simpleTypeContent">
<xs:sequence>
<xs:element name="random" type="random" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="random">
<xs:attribute name="start">
<xs:simpleType>
<xs:restriction base="xs:integer"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="end">
<xs:simpleType>
<xs:restriction base="xs:integer"/>
</xs:simpleType>
</xs:attribute>
<xs:assert test="#start le #end"/>
</xs:complexType>
<xs:complexType name="simpleTypeContent" mixed="true">
<xs:simpleContent>
<xs:extension base="type2">
<xs:attribute name="until">
<xs:simpleType>
<xs:union memberTypes="type2 annotation xs:integer until"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="condition">
<xs:simpleType>
<xs:union memberTypes="type2 annotation extended"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="repeat" type='xs:integer'/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="type2">
<xs:restriction base="xs:string">
<xs:enumeration value="Dice Roll"/>
<xs:enumeration value="Wait"/>
<xs:enumeration value="Repeat"/>
<xs:enumeration value="Double Roll"/>
<xs:enumeration value="Instruction"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="until">
<xs:restriction base="xs:string">
<xs:enumeration value="end"/>
<xs:enumeration value="random"/>
<xs:enumeration value="Instruction"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="annotation">
<xs:restriction base="xs:string">
<xs:enumeration value="rolltwice"/>
<xs:enumeration value="halfcount"/>
<xs:enumeration value="doublecount"/>
<xs:enumeration value="roll-"/>
<xs:enumeration value="roll+"/>
<xs:enumeration value="numberChange"/>
<xs:enumeration value="NoNumberChange"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="extended">
<xs:restriction base="xs:string">
<xs:enumeration value="noRolling"/>
<xs:enumeration value="noEven"/>
<xs:enumeration value="noUneven"/>
<xs:enumeration value="stopped"/>
</xs:restriction>
</xs:simpleType>
The error messages I had now all imply that this solution is invalid because of the not mixed content of simpleTypeContent or because it has simpleContent which cannot be derived from the complex content of complexTypeContent. So, how do I get it working? I cannot figure out any working solution for the problem I am facing.
As far as I understand, XSD (not even 1.1) doesn't offer a way to restrict the mixed content text to some simple type, so the only way, if you really need that single element together with a certain list of values seems to be an assertion; that means, unfortunately, you need to duplicate the values you also want for an attribute.
So some (slightly adapted, see my comment about the `#until = 'random' check) sample schema would be
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1">
<xs:element name="root">
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element name="instruction" maxOccurs="unbounded" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="type">
<xs:alternative test="#until = 'random'" type="complexTypeContent"/>
<xs:alternative type="simpleTypeContent"/>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="complexTypeContent" mixed="true">
<xs:complexContent>
<xs:extension base="simpleTypeContent">
<xs:sequence>
<xs:element name="random" type="random" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="random">
<xs:attribute name="start">
<xs:simpleType>
<xs:restriction base="xs:integer"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="end">
<xs:simpleType>
<xs:restriction base="xs:integer"/>
</xs:simpleType>
</xs:attribute>
<xs:assert test="#start le #end"/>
</xs:complexType>
<xs:complexType name="simpleTypeContent" mixed="true">
<xs:attribute name="until">
<xs:simpleType>
<xs:union memberTypes="type2 annotation xs:integer until"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="condition">
<xs:simpleType>
<xs:union memberTypes="type2 annotation extended"/>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="repeat" type='xs:integer'/>
<xs:assert test=". = ('Dice Roll', 'Wait', 'Repeat', 'Double Roll', 'Instruction')"/>
</xs:complexType>
<xs:simpleType name="type2">
<xs:restriction base="xs:string">
<xs:enumeration value="Dice Roll"/>
<xs:enumeration value="Wait"/>
<xs:enumeration value="Repeat"/>
<xs:enumeration value="Double Roll"/>
<xs:enumeration value="Instruction"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="until">
<xs:restriction base="xs:string">
<xs:enumeration value="end"/>
<xs:enumeration value="random"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="annotation">
<xs:restriction base="xs:string">
<xs:enumeration value="rolltwice"/>
<xs:enumeration value="halfcount"/>
<xs:enumeration value="doublecount"/>
<xs:enumeration value="roll-"/>
<xs:enumeration value="roll+"/>
<xs:enumeration value="numberChange"/>
<xs:enumeration value="NoNumberChange"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="extended">
<xs:restriction base="xs:string">
<xs:enumeration value="noRolling"/>
<xs:enumeration value="noEven"/>
<xs:enumeration value="noUneven"/>
<xs:enumeration value="stopped"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
and that then makes the first instruction in below sample (also slightly adapted as there was a spelling difference between the schema and the sample (Dice roll vs. Dice Roll) in your snippets) valid while the second is invalid:
<root>
<instruction>
<type repeat='1' until='random'><random start='1' end='6'/>Dice Roll</type>
</instruction>
<instruction>
<type repeat='1' until='2'><random start='1' end='6'/>Dice Roll</type>
</instruction>
</root>

xml: using conditioned attributes

I'm looking for a way to realize a scheme, where an element does have an attribute "topic" only when its enumeration has a specific value like in the upcoming example:
<article>
<type>Blogpost</type>
</article>
<article>
<type topic='news'>Article</type>
</article>
<article>
<type>Comment</type>
</article>
The challenge is to make it that the attribute will only be used when the value "Article" or "Documentary" is chosen. Furthermore I want only enumerations from predefined list to be valid. In case the right enumeration is chosen I want the attribute to be required in all other cases I don't want to have the attribute at all.
So far I tried the following schemes in order to do so but it doesn't work at all:
<xs:element name="type" minOccurs="0">
<xs:alternative test="#name='type'" type="type1"/>
<xs:alternative test="#name='type'" type="type2"/>
<xs:alternative type="xs:error"/>
</xs:element>
(...)
<xs:simpleType name="type1">
<xs:restriction base="xs:string">
<xs:enumeration value="Blogpost"/>
<xs:enumeration value="Comment"/>
<xs:enumeration value="Sentence"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="type2">
<xs:simpleContent>
<xs:extension base="type1">
<xs:attribute name="topic" type="topics" use='required'>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Article"/>
<xs:enumeration value="Documentary"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType-->
I always get an error that any chosen element is 'not a valid value of "error"'. The other example I tried worked to make use the attribute however it allowed any text and didn't care about the enumeration restrictions making it basicly useless:
<xs:element name="type" minOccurs="0">
<xs:alternative test="#ItemType='type'" type="type1"/>
<xs:alternative test="#ItemType='type'" type="type2"/>
</xs:element>
(...)
How do I do it that the same element does only have the attribute when it is actually the right enumeration and still the restrictions to enumerations are valid? Is my approach to work with xs:alternative the right one in order to have a same element one time with and one time without an attribute?
I was not able to figure out right test conditions in order to work with xs:assert.
I now have a useful answer - sorry for the non-useful comments!
This question is almost identical yours: XSD 1.1 alternative test the contents of text()
. On that basis, I suggest that you try something like this (not tested, because I don't have a XSD1.1 processor)
<xs:element name="type" type="type2" minOccurs="0"/>
<xs:complexType name="type2">
<xs:simpleContent>
<xs:extension base="type1">
<xs:attribute name="topic" type="topics" use='required'/>
<xs:assert test="not ( #topic or ( #topic and ($value eq 'Article' or $value eq 'Documentary'))"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="type1">
<xs:restriction base="xs:string">
<xs:enumeration value="Article"/>
<xs:enumeration value="Documentary"/>
<xs:enumeration value="Blogpost"/>
<xs:enumeration value="Comment"/>
<xs:enumeration value="Sentence"/>
</xs:restriction>
</xs:simpleType>```
Thank you again for your approach #kimbert.
With your help I was able to figure out the assertion that is fullfilling the demand. I just had to adjust your idea slightly:
<xs:element name="type" type="type2" minOccurs="0"/>
<xs:complexType name="type2">
<xs:simpleContent>
<xs:extension base="type1">
<xs:attribute name="topic" type="topics"/>
<xs:assert test="#topic and ($value eq 'Article' or $value eq 'Documentary') or not ($value eq 'Article' or $value eq 'Documentary')"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="type1">
<xs:restriction base="xs:string">
<xs:enumeration value="Article"/>
<xs:enumeration value="Documentary"/>
<xs:enumeration value="Blogpost"/>
<xs:enumeration value="Comment"/>
<xs:enumeration value="Sentence"/>
</xs:restriction>
</xs:simpleType>
Like this the compiler now always demands the attribute "topic" in case the value "Article" or "Documentary" is asked for. In all other cases the attribute is ignored as it should be.

How to use condition in maxInclusive restriction in xsd

I am using schema version 1.0. I want to put condition on maxInclusive.
Like
if person selected minor(age<18) then in age textbox he should not be able to enter more than 18
if he selected adult then we can have age limit till 123
Any help will be appreciated.
Try this.
<xs:element name="person">
<xs:element ref="age"/>
</xs:element>
<xs:element name="age">
<xs:alternative test="#PersonType='Age'" type="MinorAgeType"/>
<xs:alternative test="#PersonType='Age'" type="AdultAgeType"/>
<xs:alternative type="xs:error"/>
</xs:element>
<xs:simpleType name="MinorAgeType">
<xs:restriction base="xs:integer">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="17"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="AdultAgeType">
<xs:restriction base="xs:integer">
<xs:minInclusive value="18"/>
<xs:maxInclusive value="123"/>
</xs:restriction>
</xs:simpleType>

XML Schema validator error on attribute declaration

I get an error on validation:
Error - Line 14, 36: org.xml.sax.SAXParseException; lineNumber: 14; columnNumber: 36; s4s-elt-must-match.1: The content of 'simpleType' must match (annotation?, (restriction | list | union)). A problem was found starting at: attribute.
How to resolve it?
My XML fragment
<CHANEL_NAME lang="RUS/MD">N4</CHANEL_NAME>
And XSD:
<xs:element name="CHANEL_NAME">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:length value="40"/>
</xs:restriction>
<xs:attribute name="lang">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="MD"/>
<xs:enumeration value="RUS"/>
<xs:enumeration value="RUS/MD"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:simpleType>
</xs:element>
So I need in attribute 'lang' only determined values like 'MD', 'RUS' or 'RUS/MD'. I read examples and I guess it's OK.
Or is enumeration only for elements and not for attributes?
The problem is the first simpleType. Simple types can't have attribute.
You probably need a complex type with simple content. Something like:
<xs:element name="CHANEL_NAME">
<xs:complexType>
<xs:simpleContent>
<xs:restriction base="xs:string">
<xs:length value="40"/>
<xs:attribute name="lang">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="MD"/>
<xs:enumeration value="RUS"/>
<xs:enumeration value="RUS/MD"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
(Not tested.)
Also consider naming your anonymous types.
ps. Also consider using/restricting xs:language as language type.
Всего наилучшего.

How can I extend restrictions on simple type element?

Could somebody post an example about how to add enumerated restriction on simpletype element in xml schema?
<xs:simpleType name="myElement">
<xs:union memberTypes="previousRestrictions">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="close" />
</xs:restriction>
</xs:simpleType>
</xs:union>
</xs:simpleType>
In this example, the fruit element must be a string whose value is in the set {"apple", "banana", "coconut"}.
<xs:element name="fruit">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="apple"/>
<xs:enumeration value="banana"/>
<xs:enumeration value="coconut"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
So, this is valid:
<fruit>banana</fruit>
but this is not:
<fruit>kumquat</fruit>

Resources