XML Schema for a fixed element with a fixed attribute? - xsd

What would be the correct XML Schema 1.0 declaration for a
<notice xml:lang="en">Banana banana banana</notice>
where:
The xml:lang attribute is compulsory
The value "en" is fixed and compulsory
The content of notice is simple text.
The content of notice is fixed (as above) and compulsory?
My best (but wrong) effort is the following fragment:
<xs:element name="notice" use="required" fixed="Banana banana banana">
<xs:complexType>
<xs:simpleContent>
<xs:extension>
<xs:attribute ref="xml:lang" use="required" fixed="en"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="http://www.w3.org/XML/1998/namespace" />
<xs:element name="notice" type="notice"/>
<xs:complexType name="notice">
<xs:simpleContent>
<xs:extension base="CONTENT">
<xs:attribute ref="xml:lang" use="required" fixed="en"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="CONTENT">
<xs:restriction base="xs:string">
<xs:enumeration value="Banana banana banana"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>

Related

How to Extend a XSD Restriction/Pattern Value

I am trying to restrict the values for two Elements that can share (most of) the same attribute 'type' values. I'd like to be able to extend those values for one of the Elements (see sample code below -- the 'End' element's 'Value' attribute can have the same entries as the 'Start' element's 'Value' attribute, but there can be additional values). I don't think my solution in the example is correct; is there a simple solution that I can follow?
<xsd:simpleType name="StartAndEndTypeType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="(value1|value2|value3"/>
</xsd:restriction>
</xsd:simpleType>
<xs:element name="Start">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:float">
<xs:attribute name="Value" type="StartAndEndTypeType"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="End">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:float">
<xs:attribute name="Value" type="StartAndEndTypeType|value4"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
This can be done in a number of ways.
Note I've changed your pattern facet to an enumeration as it works better for the example (but a pattern facet could be put back if required)
1 - Restricting a type
The StartAndEndTypeType contains all the values required, and then you restrict the ones you don't want in the StartType.
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid Studio 2019 BETA (https://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="StartAndEndTypeType">
<xs:restriction base="xs:string">
<xs:enumeration value="value1" />
<xs:enumeration value="value2" />
<xs:enumeration value="value3" />
<xs:enumeration value="value4" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="StartType">
<xs:restriction base="StartAndEndTypeType">
<xs:enumeration value="value1" />
<xs:enumeration value="value2" />
<xs:enumeration value="value3" />
</xs:restriction>
</xs:simpleType>
<xs:element name="Start">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:float">
<xs:attribute name="Value" type="StartType" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="End">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:float">
<xs:attribute name="Value" type="StartAndEndTypeType" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:schema>
2 - Extend the base definition using a union
You define the base type StartAndEndTypeType, then add to it the additional values you want to allow using an xs:union.
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid Studio 2019 BETA (https://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="StartAndEndTypeType">
<xs:restriction base="xs:string">
<xs:enumeration value="value1" />
<xs:enumeration value="value2" />
<xs:enumeration value="value3" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="EndType">
<xs:union memberTypes="StartAndEndTypeType">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="value4" />
</xs:restriction>
</xs:simpleType>
</xs:union>
</xs:simpleType>
<xs:element name="Start">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:float">
<xs:attribute name="Value" type="StartAndEndTypeType" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="End">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:float">
<xs:attribute name="Value" type="EndType" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:schema>

XSD reusing nodes or duplication

I wanted to know the proper way to do an xsd as certain nodes in my xsd may be reused in other xsd's. Like in Search Item request I will use
<xs:element name="Item">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string"/>
<xs:element name="Price" type="xs:double"/>
<xs:element name="SupplierCode" type="xs:string"/>
<xs:element name="Supplier" type="xs:string"/>
<xs:element name="SupplierName" type="xs:string"/>
<xs:element name="Manufacturer" type="xs:string"/>
<xs:element ref="CustomerReviews" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="model" type="xs:string" use="required"/>
<xs:attribute name="href" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
then I might need to use it in another xsd.
So should I repeat it or make a xsd with it in it and reference it?
My Current xsd with include
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns1="http://www.itwholesaledeluxe.com" targetNamespace="http://www.itwholesaledeluxe.com" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:include schemaLocation="Item.xsd"/>
<xs:element name="Search-Item-Request">
<xs:complexType>
<xs:sequence>
<xs:element name="Items">
<xs:complexType>
<xs:sequence>
<xs:element name="Item" type="Item"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Then the item xsd partially since its too big to post
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" targetNamespace="http://www.itwholesaledeluxe.com">
<xs:complexType name="Item">
<xs:sequence>
<xs:element name="Name">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="50"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</sequence>
</complexType>
</xs:schema>
follow DRY: If it's the same object (in the same namespace): make an xsd and reference it.
That way, if the object is altered at some point, you only need to make your changes once. Also, any code generated for this object only needs to be generated once.
Use the following xsd's as a reference:
Main.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ns1="http://www.itwholesaledeluxe.com" targetNamespace="http://www.itwholesaledeluxe.com"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:include schemaLocation="Item.xsd" />
<xs:element name="Search-Item-Request">
<xs:complexType>
<xs:sequence>
<xs:element name="Items">
<xs:complexType>
<xs:sequence>
<xs:element name="Item" type="ns1:Item" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Item.xsd:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" attributeFormDefault="unqualified"
targetNamespace="http://www.itwholesaledeluxe.com">
<xs:complexType name="Item">
<xs:sequence>
<xs:element name="Name">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="50" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>

XML Schema Question

Is it possible to define an XML Schema (XSD) to correctly describe a document such as the following?
<root>
<str name="status">success</str>
<str name="message">Your request has been processed successfuly.</str>
</root>
The problem might be that the <str> tags have an attribute (name) as well as string values.
I would be grateful if anyone could come up with an XML Schema for this piece of XML, since I am kind of stuck at this point. My best attempt so far is shown below, but botice that the <str> element cannot have a type (such as xsd:string) in this context.
<xs:element name="object">
<xs:complexType>
<xs:sequence>
<xs:element name="str" minOccurs="2" maxOccurs="2">
<xs:complexType>
<xs:sequence>
<xs:element name="productName" type="xs:string"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
Your constraints are not entirely clear, so a number of schemas would validate the XML depending on how loose/tight you would want the validation to be. This example shows a schema that mandates exactly two elements inside the element and they must have a "name" attribute with the values "status" or "message".
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="str" type="StrType" minOccurs="2" maxOccurs="2"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="StrType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="name" type="StrAttribute" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:simpleType name="StrAttribute">
<xs:restriction base="xs:string">
<xs:enumeration value="status"/>
<xs:enumeration value="message"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
Of course, this would allow two elements both with the name attribute set to "message", or with "message" first, then status. I believe the schema cannot define a sequence containing two elements of the same name but different types which you would need if you required the validation to ensure that the first always contained "status" and the second one contained "message".

XML schema and problem when deriving from mixed type

I have following XML schema:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="content" type="contentType"/>
<xs:complexType name="contentType">
<xs:complexContent>
<xs:extension base="versionedElementType">
<xs:sequence>
<xs:element name="item" type="itemType" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="itemType" mixed="true">
<xs:complexContent>
<xs:extension base="itemTypeBase">
<xs:sequence>
<xs:element name="order" type="xs:unsignedInt"/>
<xs:element name="id" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<!-- Simple type convert to complex type -->
<xs:complexType name="itemTypeBase" mixed="true">
<xs:simpleContent>
<xs:extension base="itemDescriptionType">
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<!-- Simple type -string restriction -->
<xs:simpleType name="itemDescriptionType" >
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="64"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="versionedElementType">
<xs:attribute name="version" type="xs:string" use="required"/>
</xs:complexType>
</xs:schema>
which I use to validate this XML instance (I want to mix the text in the 'item' element with sub-elements 'order' and 'id'):
<?xml version="1.0" encoding="UTF-8"?>
<content xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="Content.xsd"
version ="1.0">
<item>Description here...
<order>2</order>
<id>2</id>
</item>
</content>
Whatever I did the validation still says taht there is an error:
The content type of a derived type and that of its base must both be mixed or both be element-only. Type 'itemType' is mixed, but its base type is not.
But I can see that both types - itemType and itemTypeBase are MIXED!!
Thanks a lot
STeN
First of all the error which I see if I open your schema in Visual Studio 2010 is:
The derived type and the based type
must have the same content type.
In you current schema the type itemTypeBase is defined with respect of the <xs:simpleContent> and derived type itemType with the respect of <xs:complexContent> which is not allowed. Either you allow no sub-elements and use <xs:simpleContent> or you do use child elements and use <xs:complexContent>.
I personally don't like and don't use mixed types. If I understand you correct you want to make some restrictions in the text from the content. You want to have the content length between 1 and 64 characters. But <order>2</order>, <id>2</id> and all whitespace, inclusive the new line characters, are also a part of the content. If you want that <item> has simple content, then you can not insert child elements inside.
So the pragmatical solution would be go away from the mixed model and use the XML document in the form
<?xml version="1.0" encoding="utf-8"?>
<content xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="Content.xsd"
version ="1.0">
<item>
<description>Description here...</description>
<order>2</order>
<id>2</id>
</item>
</content>
where Content.xsd is
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="content" type="contentType"/>
<xs:complexType name="contentType">
<xs:sequence>
<xs:element name="item" type="itemType"
minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="version" type="xs:string" use="required"/>
</xs:complexType>
<xs:complexType name="itemType">
<xs:sequence>
<xs:element name="description" type="itemDescriptionType"/>
<xs:element name="order" type="xs:unsignedInt"/>
<xs:element name="id" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="itemDescriptionType" >
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="64"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
All will be very simple and clear.

How to validate empty string value tag in xsd

I have an xml file which is having some date values and other datatypes.
<Purchasedate Name="purcaseDate" value=""/>
I am validating these xml files with a xsd file.
In xsd shcema I have written a regular expression pattern for dd/mm/yyyy format.
This is working fine if value attribute have a value.
My pattern is validating against the value attribute.
The field (purchasedate) is not mandatory.
if value="", this means my pattern is validating against an empty string also, which is not mandatory.
I need to validate the optional field
and i am using <xs:attribute name="PurchaseDate" use="optional"> also.
I need to validate this field when value tag is not empty.
That's too easy ..
Just all you have to do is to include empty string specification in your pattern
This is the way to do that ..
<xs:pattern value="|(Regular_pattern_goes_here)"/>
For your reference I have written a sample chunks of codes .. just go through them ..
sample XML:
<?xml version="1.0" encoding="utf-8"?>
<xmln xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com XMLFile1.xsd" xmlns="http://www.xsdef.com/xml/123">
<Purchasedate Name="purcaseDate" value=""/>
</xmln>
sample XSD:(includes custom type def)
<xs:schema xmlns:xsLocal="http://www.xsdef.com/xml/123" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.xsdef.com/xml/123" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="xmln">
<xs:complexType>
<xs:sequence>
<xs:element name="Purchasedate">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="Name" type="xs:string" use="required" />
<xs:attribute name="value" type="xsLocal:CUSTOM_DATE" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="CUSTOM_DATE">
<xs:restriction base="xs:string">
<xs:pattern value="|((01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31)/(01|02|03|04|05|06|07|08|09|10|11|12)/[1-2][0-9][0-9][0-9])"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
try adding this attribute nillable="true" into the xml tag definition
Also you can take a look at his link http://www.zvon.org/xxl/XMLSchemaTutorial/Output/ser_over_st0.html
Best Reagds,
Iordan
The '?' character in the Regex means that the character before it must occur 0 or 1 times.
So in order to solve your issue you need to wrap the regex in parenthesis and put a questionmark at the end:
<xs:simpleType name="PurchaseDateType">
<xs:restriction base="xs:string">
<xs:pattern value="(Regular_pattern_goes_here)?"/>
</xs:restriction>
</xs:simpleType>
Use this type on your field and you should be fine
If you control the syntax of the XML, you should consider defining the element as follows. Since XML-Schema already provides a date type, you should use it unless you have a really good reason. I say this because it will make it easier for others to use the xml and for you to use better code frameworks later. I didn't include the "name" attribute because it seemed redundant to the element name.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="Purchasedate" nillable="true" type="xs:date"/>
<xs:element name="Purchasedate2">
<xs:complexType>
<xs:attribute name="value" type="xs:date"/>
</xs:complexType>
</xs:element>
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element ref="Purchasedate"/>
<xs:element minOccurs="0" ref="Purchasedate2"/>
</xs:sequence>
</xs:complexType>
</xs:element>

Resources