How can I add max length, required attributes: Yes in XML schema? - xsd

I know there are two ways to define simple elements in XML schema. How can I add only maxlength and required attribute YES to simple element definition. in the following two examples.
<xs:element name="Xyz">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="4"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="Xyz" type="xs:string" minOccurs="0" maxOccurs="1"/>

Define your restricted text content as a global (=named) <xs:simpleType> then use this as a base type for <xs:extension> that you need when create a new type by extension to add the attribute.
Type definition of an element that has attributes must be <xs:complexType>. Then again if the element content can be only text or attributes but not elements, the content must be defined as <xs:simpleContent>. Sample code below.
<!-- definition of the restricted string -->
<xs:simpleType name="restrictedLength">
<xs:restriction base="xs:string">
<xs:maxLength value="4" />
</xs:restriction>
</xs:simpleType>
<!-- definition for the element with an attribute and text content -->
<xs:element name="Xyz">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="restrictedLength">
<xs:attribute name="YES" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
For more complete explanation on extending simple content elements with attribute see this:
http://www.xml.com/pub/a/2001/08/22/easyschema.html

Related

Problem with restriction in xsd complex type inheritance

I have the a little problem with the xsd below. I have created a type of vaultobject with a type attribute that can have any value in a enumeration. Then I derived VaultServiceObject from vaultobject en set a restriction to limit type to a fixed value for the derived object.
The editor (liquid-xml) design service seems to understand this and displays correctly, but the text editor marks the line 26 as and error.
<xs:attribute name="Type" fixed="ServiceConfiguration" type="xs:string" use="required">
Saying "Error Invalid attribute restriction. Derived attribute's type is not a valid restriction of the base attribute's type." So from this I guess "xs:string" is wrong. But I cannot figure out what type I should use.
Hopefully there is someone more experienced with XSD out there.
p.s I cobbled xsd below together from several other similar stackoverflow questions, but they do not supply this exact combination and its solution. So please do not point to those without explaining what I am looking for.
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid Studio 2020 (https://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="VaultObject">
<xs:sequence>
<xs:annotation>
<xs:documentation>Allows for derived object to have a sequence of elements</xs:documentation>
</xs:annotation>
</xs:sequence>
<xs:attribute name="Type" use="required">
<xs:annotation>
<xs:documentation>This is the list of possible vault objects. Derived objects need to lock this down to the object type the represent.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Merge" />
<xs:enumeration value="ServiceConfiguration" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:anyAttribute />
</xs:complexType>
<xs:complexType name="VaultServiceConfigurationObject">
<xs:complexContent>
<xs:restriction xmlns:q2="http://www.it-workz.nl/IDM" base="VaultObject">
<xs:attribute name="Type" fixed="ServiceConfiguration" type="xs:string" use="required">
<xs:annotation>
<xs:documentation xml:lang="EN">This property is inherited from VaultObject, but is locked down to the fixed value of "ServiceConfiguration"</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="ServiceType">
<xs:annotation>
<xs:documentation xml:lang="EN">The list of possible service types we support. Derived service definitions need to lock this down to a single value in their own type.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="SystemA" />
<xs:enumeration value="SystemB" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="Name" type="xs:string" use="required">
<xs:annotation>
<xs:documentation xml:lang="EN">Every service needs to be uniquely named. Even between different service types.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:schema>
You can do this by breaking the 'Type' enum out into it's own SimpleType.
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid Studio 2020 (https://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="VaultObjectType">
<xs:restriction base="xs:string">
<xs:enumeration value="Merge" />
<xs:enumeration value="ServiceConfiguration" />
</xs:restriction>
</xs:simpleType>
<xs:complexType name="VaultObject">
<xs:sequence>
<xs:annotation>
<xs:documentation>Allows for derived object to have a sequence of elements</xs:documentation>
</xs:annotation>
</xs:sequence>
<xs:attribute name="Type" type="VaultObjectType" use="required">
<xs:annotation>
<xs:documentation>This is the list of possible vault objects. Derived objects need to lock this down to the object type the represent.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:anyAttribute />
</xs:complexType>
<xs:complexType name="VaultServiceConfigurationObject">
<xs:complexContent>
<xs:restriction xmlns:q2="http://www.it-workz.nl/IDM" base="VaultObject">
<xs:attribute name="Type" fixed="ServiceConfiguration" type="VaultObjectType" use="required">
<xs:annotation>
<xs:documentation xml:lang="EN">This property is inherited from VaultObject, but is locked down to the fixed value of "ServiceConfiguration"</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="ServiceType">
<xs:annotation>
<xs:documentation xml:lang="EN">The list of possible service types we support. Derived service definitions need to lock this down to a single value in their own type.</xs:documentation>
</xs:annotation>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="SystemA" />
<xs:enumeration value="SystemB" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="Name" type="xs:string" use="required">
<xs:annotation>
<xs:documentation xml:lang="EN">Every service needs to be uniquely named. Even between different service types.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:schema>

XSD validation error in #AnonType_Apps

When I tried to validate my XSD it gives the error
S4s-elt-invalid-content.1: The Content Of '#AnonType_Apps' Is Invalid.
Element 'sequence' Is Invalid, Misplaced, Or Occurs Too Often.
don't know what should be done
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name ="Apps">
<xs:complexType>
<xs:attribute name ="List_Type" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="new releases"/>
<xs:enumeration value="top rated"/>
<xs:enumeration value="category list"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name ="Server_IP" type="xs:string" fixed="10.144.50.55"/>
<xs:sequence>
<xs:element name ="App" minOccurs="1" maxOccurs="20">
<xs:complexType>
<xs:attribute name ="device_type" use="optinal" >
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="tablet"/>
<xs:enumeration value="phone"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name ="app_id" type="xs:string"/>
<xs:attribute name ="installed" type="xs:boolean" default="false"/>
<xs:sequence>
<xs:element name ="app_name" type="xs:string"></xs:element>
<xs:element name ="catogry" minOccurs="1" maxOccurs="3"></xs:element>
<xs:element name ="version" type="xs:string"></xs:element>
<xs:element name ="description" type="xs:string"></xs:element>
<xs:element name ="reviews" use="required">
<xs:complexType>
<xs:sequence>
<xs:element name ="review" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:all>
<xs:element name ="reviewer_name" type="xs:string"></xs:element>
<xs:element name ="review_date">
<xs:complexType>
<xs:restriction base="xs:string">
<xs:pattern value="\d{4}\-\d{2}\-\d{2}"/>
</xs:restriction>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name ="review_time">
<xs:complexType>
<xs:restriction base="xs:string">
<xs:pattern value="\d{2}:\d{2}:\d{}"/>
</xs:restriction>
</xs:complexType>
</xs:element>
<xs:element name ="content" type="xs:string"></xs:element>
<xs:element name ="rating">
<xs:complexType>
<xs:restriction base="xs:float">
<xs:minInclusive value="0" />
<xs:maxInclusive value="5" />
</xs:restriction>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Within a complexType element, the content model comes first and the attribute declarations come last. Move the outermost sequence element to make it the first child of the complex type.
You might want to try finding a syntax-aware editor in which to edit schema documents, to alert you to problems of this kind.
Other syntactic issues in this fragment:
Other complexType elements have the same syntax error of putting their attribute declarations first.
If you want the type of rating to be a restriction of xs:float, then you want it to have a simple type, not a complex type.
Ditto for review_time and review_date.
The pattern on the type of review_time is not a legal regular expression: braces may contain information on the minimum and/or maximum occurrences of (strings matching) a subexpression, in a variety of forms, but they must contain something, so \d{} is not a legal expression. Drop the empty braces, or make it \d{1} if you like, or make it say what you want.
The xs:element element has no attribute named use; I think you may mean to say <xs:element name="reviews" minOccurs="1" maxOccurs="1"> ...
The use attribute does not accept the value optinal.
Get an editor!
Your xs:sequence element needs to follow immidiately on the complexType element.
Your review_date and review_time elements should be a simpleType with a restriction.
If you fix those issues your xsd seems validd.

Element-Mandatory Attribute declaration in XSD Schema:

I want to declare an element to be included in a complex type declaration, and the element has a mandatory attribute: "option=MyOption", but the value of the "option" attribute could be anything, depending on the context.
That is: the attribute "option" with some unknown value should be mandatory in any document using the complex type containing this element.
Example:
<xs:element name="SpecialOption" type="xs:string"/>
<xs:complexType name="SpecialOptions">
<xs:sequence>
<xs:element ref="SpecialOption" minOccurs="1" maxOccurs="100"/>
<xs:element ref="XXX"/>
</xs:sequence>
</xs:complexType>
In this case the "SpecialOption" element in the complex type "SpecialOptions" should have this mandatory attribute.
I don't know how to declare a mandatory attribute for an element in XSD, or how to specify that the attribute must have a value that is not yet known.
You need to modify the definition of the "SpecialOption" element to include the required attribute. Update this code:
<xs:element name="SpecialOption" type="xs:string"/>
to this:
<xs:element name="SpecialOption">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Option" type="xs:string" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
With this change your complex type will contain the required "Option" attribute on all instances of the "SpecialOption" element in the "SpecialOptions" complex type. Declaring the "Option" attribute to be of type xs:string will allow any value to be passed in this field.
1) This is a simple required string attribute
<xs:element name="SpecialOption">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Option" type="xs:string" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
2) To require exactly one of a list of allowed values:
<xs:element name="SpecialOption">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Option" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="DE"/>
<xs:enumeration value="EN"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
3) One can use a range as a restriction, like in the example below.
<xs:element name="SpecialOption">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Option" use="required">
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="95"/>
<xs:maxInclusive value="137"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
4) Below, the attribute is declared as a list containing decimal values. This allows an attribute to contain a subset of the specified values, e.g. Option="6 77 95".
<xs:simpleType name="Items">
<xs:restriction base="xs:decimal">
<xs:enumeration value="137"/>
<xs:enumeration value="95"/>
<xs:enumeration value="6"/>
<xs:enumeration value="77"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="SpecialOption">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Option" use="required">
<xs:simpleType>
<xs:list itemType="Items"/>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
5) Here the attribute is declared optional, but provided with a default value ("test"), which is sometimes sufficient:
<xs:element name="SpecialOption">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Option" type="xs:string" use="optional" default="test"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
To mark an attribute as mandatory you use <xs:attribute use="required" />.
As for type, you have a choice of the built-in XSD types (xs:string etc), or you can define your own <xs:simpleType /> and use that.
UPDATE
I am not certain what you mean by the attribute must have a value that is not yet known. Does this mean that the value is a string, but can be any string? Or a decimal?
Because it's an attribute value we are talking about you are restricted to using the built-in XSD types, or defining your own xs:simpleType type based on one of the built-in types. This is where you can apply more stringent rules to the allowed value, for example by extending xs:string and adding a regular expression constraint to allowed values.
<xsd:simpleType name="UKDate">
<xsd:restriction base="xsd:string">
<xsd:pattern value="(0?[1-9]|[12][0-9]|3[01])[- /.](0?[1-9]|1[012])[- /.](19|20)\d\d"/>
</xsd:restriction>
</xsd:simpleType>
However, if there is absolutely no way of knowing what value will be used then you have the well known temporal paradox whereby you cannot restrict something at design-time to a value you only know at run-time. In this instance, surely it is only necessary to specify that the attribute must at least be present?
<xs:attribute use="required" />
Hope this answers your question a little more clearly.
Simply you can do it as the following
<xs:element name="SpecialOption">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:whiteSpace value="replace"/>
<xs:minLength value="1"></xs:minLength>
</xs:restriction>
</xs:simpleType>
</xs:element>
by this code you enforce to insert a value on the xml tag and also the white space restriction will handle to remove the white space from the xml tag.

XML Schema - I need to make sure I have 2 instances of an element, one with each attribute

I need to make sure I have 2 instances of an element, one with each attribute.
Essentially I need both:
/*:SalesPersonParty/*:PartyID[#schemeAgencyName="SalesPersonID"]
AND
/*:SalesPersonParty/*:PartyID[#schemeAgencyName="SalesPersonPduID"]
I have cardinality 2..2 but 2 instances of either attribute is valid. I need one of each and order doesn't matter.
Here are the relevant schema components:
<xs:simpleType name="RestrictedString">
<xs:restriction base="xs:string">
<xs:pattern value="([0-9]{3})|([0-9]{10})" />
</xs:restriction>
</xs:simpleType>
<xs:element name="SalesPersonParty" minOccurs="2" maxOccurs="2">
<xs:complexType>
<xs:sequence>
<xs:element name="PartyID" minOccurs="1" maxOccurs="1">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="star:RestrictedString">
<xs:attribute name="schemeAgencyName" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="SalesPersonID" />
<xs:enumeration value="SalesPersonPduID" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
Is this even possible?
Thanks and regards,
Tony
I think you can do it with a uniqueness constraint. You'll have to know the container element for SalesPersonParty element; call it Transaction. Then you need something like:
<xs:element name="Transaction">
...
<xs:unique name="uniqueAgencyNameConstraint">
<xs:selector xpath="SalesPersonParty/PartyID">
<xs:field xpath="#schemeAgencyName"/>
</xs:unique>
</xs:element>
This says that each SalesPersonParty/PartyID must have a unique schemeAgencyName. Combined with the constraints of having exactly two SalesPersonParty elements and only two possible values in the enumeration, all values must occur once.

Having both an attribute and a restriction on an element in xml schema

I'm trying to write a xml schema that will validate this piece of xml:
<date isodate="2007-03-14">14 march 2007</date>
The attribute isodate should have it's type set to xs:date and the content should be max 50 characters long.
I wonder if it's possible to write the xml schema definition in one block, something like this maybe:
<xs:element name="date" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:simpleContent>
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
<xs:maxLength value="50"/>
</xs:restriction>
<xs:attribute name="isodate" type="xs:date" use="required"/>
</xs:simpleContent>
</xs:complexType>
</xs:element>
The code above doesn't work, and I can't really figure out why. Only workaround I have found is to break out the restriction part into a separate type, and link that like this:
<xs:simpleType name="reviewDate">
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
<xs:maxLength value="50"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="date" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="reviewDate">
<xs:attribute name="isodate" type="xs:date" use="required"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
The question I have is how to write the definition in one block so that the schema is a bit more readable, and doesn't reference types in other parts of the schema.
You cannot merge both a restriction and an extension into one block of XSD. The solution that you have with the "ReviewDate" simple type is the best solution I know of.
Marc
You can have a element with restriction and attribute(-s).
The key is to define custom type with it's restrictions and then using it add attributes to it.
Refer here: Content restriction and attribute validation on the same element in XSD

Resources