how to declare multiple groups in XSD? - xsd

In my scenario my XSD should have multiple groups under one root tag,
#XSD#
<xs:group name="location">
<xs:sequence>
<xs:element name="city" type="xs:string"/>
<xs:element name="flat_num" type="xs:string"/>
<xs:element name="landmark" type="xs:string"/>
<xs:element name="street" type="xs:string"/>
</xs:sequence>
</xs:group>
<xs:group name="student">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:element name="mothername" type="xs:string"/>
<xs:element name="fathername" type="xs:string"/>
</xs:sequence>
</xs:group>
<xs:element name="Student_details" type="details"/>
<xs:complexType name="details">
<xs:group ref="location"/>
<xs:group ref="student"/>
</xs:complexType>
</xs:schema>
When i am validating with xml , it says this format is wrong ,
can any one help to let me know how to create multiple groups

Your missing the Sequence in the complex type
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid Studio 2017 - Developer Bundle Edition (Trial) 15.0.0.7089 (https://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:group name="location">
<xs:sequence>
<xs:element name="city" type="xs:string" />
<xs:element name="flat_num" type="xs:string" />
<xs:element name="landmark" type="xs:string" />
<xs:element name="street" type="xs:string" />
</xs:sequence>
</xs:group>
<xs:group name="student">
<xs:sequence>
<xs:element name="firstname" type="xs:string" />
<xs:element name="lastname" type="xs:string" />
<xs:element name="mothername" type="xs:string" />
<xs:element name="fathername" type="xs:string" />
</xs:sequence>
</xs:group>
<xs:element name="Student_details" type="details" />
<xs:complexType name="details">
<xs:sequence>
<xs:group ref="location" />
<xs:group ref="student" />
</xs:sequence>
</xs:complexType>
</xs:schema>
I would also question whether a group best implements what you are trying to describe. What you have currently will produce XML like this
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid Studio 2017 - Developer Bundle Edition (Trial) 15.0.0.7089 (https://www.liquid-technologies.com) -->
<Student_details xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="Schema.xsd">
<city>string</city>
<flat_num>string</flat_num>
<landmark>string</landmark>
<street>string</street>
<firstname>string</firstname>
<lastname>string</lastname>
<mothername>string</mothername>
<fathername>string</fathername>
</Student_details>

Related

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>

xsd error in the following

here is the xml
<?xml version="1.0" encoding="utf-8"?>
<Modules xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="XSDQu3.xsd">
<Module code="CSE1246">
<Name shortName="ADSA">Applied Data Structures and Algorithms</Name>
<Level>1</Level>
<ResourcePerson>
<Name>Anwar</Name>
<Surname>Chutoo</Surname>
</ResourcePerson>
</Module>
<Module code="CSE2041">
<Name shortName="Web 2">Web Technologies II</Name>
<Level>2</Level>
<ResourcePerson>
<FullName>Shehzad Jaunbuccus</FullName>
</ResourcePerson>
</Module>
</Modules>
i'm having an error at name. a resource person can either contain fullname or name and surname. please help. Am i correctly doing this part
here is the xsd
<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="NameNSurnameType">
<xs:sequence>
<xs:element name="Name" type="xs:string"/>
<xs:element name="Surname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ResourcePersonType">
<xs:sequence>
<xs:choice>
<xs:element name="NameNSurnameType" type="NameNSurnameType"/>
<xs:element name="FullName" type="xs:string"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
<xs:attribute name="code">
<xs:simpleType>
<xs:restriction base="xs:ID">
<xs:pattern value="CSE(\d{4})"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:complexType name="nameType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="shortName" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name="Modules">
<xs:complexType>
<xs:sequence>
<xs:element name="Module" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="nameType"/>
<xs:element name="Level" type="xs:positiveInteger"/>
<xs:element name="ResourcePerson" type="ResourcePersonType"/>
</xs:sequence>
<xs:attribute ref="code" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
I can see your confusion; a choice "option" can be almost any particle; a compositor (such as xs:sequence or another xs:choice) would match the description. The minimum you need to do is change the following definition.
<xs:complexType name="ResourcePersonType">
<xs:sequence>
<xs:choice>
<xs:sequence>
<xs:element name="Name" type="xs:string"/>
<xs:element name="Surname" type="xs:string"/>
</xs:sequence>
<xs:element name="FullName" type="xs:string"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
If you want to reference the name as you seem to want to do it with the global complex type, then one can create a group and reference that instead. Below is a modified XSD consistent with the above scenario:
<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:group name="NameNSurnameType">
<xs:sequence>
<xs:element name="Name" type="xs:string"/>
<xs:element name="Surname" type="xs:string"/>
</xs:sequence>
</xs:group>
<xs:complexType name="ResourcePersonType">
<xs:sequence>
<xs:choice>
<xs:group ref="NameNSurnameType"/>
<xs:element name="FullName" type="xs:string"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
<xs:attribute name="code">
<xs:simpleType>
<xs:restriction base="xs:ID">
<xs:pattern value="CSE(\d{4})"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:complexType name="nameType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="shortName" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:element name="Modules">
<xs:complexType>
<xs:sequence>
<xs:element name="Module" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="nameType"/>
<xs:element name="Level" type="xs:positiveInteger"/>
<xs:element name="ResourcePerson" type="ResourcePersonType"/>
</xs:sequence>
<xs:attribute ref="code" use="required"/>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

XSD schema - Either one or both

I it possible to make a choice scenario, like (A or B or Both). If yes, how can this be done with the following elements?
<xs:element name="a" type="typeA" />
<xs:element name="b" type="typeB" />
Hope you can help.
Regards,
Nima
You can see XSD "one or both" choice construct leads to ambiguous content model
<xs:schema xmlns:xs="...">
<xs:element name="a" type="typeA" />
<xs:element name="b" type="typeB" />
<xs:element name="...">
<xs:complexType>
<xs:sequence>
<xs:choice>
<xs:sequence>
<xs:element ref="a"/>
<xs:element ref="b" minOccurs="0"/>
</xs:sequence>
<xs:element ref="b"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

Problem with xml schema elements hierarchy

What's wrong with this xml schema? It doesn't parse correctly, and I can't realize a hierarchy between cluster(element)->host(element)->Load(element).
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="cluster">
<xs:complexType>
<xs:sequence>
<xs:element ref="host"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="host">
<xs:complexType>
<xs:element ref="Load"/>
<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="Load">
<xs:complexType>
<xs:attribute name="usedPhisicalMemory" type="xs:integer"/>
</xs:complexType>
</xs:element>
</xs:schema>
Thank you, Emilio
To allow something like this (I corrected the typo in "usedPhysicalMemory"):
<cluster>
<host name="foo">
<Load usedPhysicalMemory="500" />
</host>
<host name="bar">
<Load usedPhysicalMemory="500" />
</host>
</cluster>
This schema would do it:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="cluster">
<xs:complexType>
<xs:sequence>
<xs:element ref="host" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="host">
<xs:complexType>
<xs:sequence>
<xs:element ref="Load" />
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="Load">
<xs:complexType>
<xs:attribute name="usedPhysicalMemory" type="xs:integer" />
</xs:complexType>
</xs:element>
</xs:schema>
From the MSDN on <xs:complexType> (because the spec makes my brain hurt):
If group, sequence, choice, or all is specified, the elements must
appear in the following order:
group | sequence | choice | all
attribute | attributeGroup
anyAttribute
Maybe someone else can point out the relevant section in the spec.
In the host element, the load element cannot be a child of complexType, you must have a sequence, etc. in between.

XML schema for elements with same name but different sub-structure depending on context

I try to define a schema for XML documents I receive.
The documents look like:
<root>
<items>
<group name="G-1">
<item name="I-1"/>
<item name="I-2"/>
<item name="I-3"/>
<item name="I-4"/>
</group>
</items>
<data>
<group name="G-1" place="here">
<customer name="C-1">
<item name="I-1" count="3"/>
<item name="I-2" count="4"/>
</customer>
<customer name="C-2">
<item name="I-3" count="7"/>
</customer>
</group>
</data>
</root>
I tried XmlSpy and xsd.exe from .NET 2.0. Both created schema definitions which allow below <group> any number of <item> and <customer> elements. But what I'm looking for should restrict <group> below <items> to <item> elements, and <group> below <data> to <customer> elements.
Is this something xml schema is not capable at all?
The key points (see XML Schema Runtime Polymorphism via xsi:type and Abstract Types for complete and correct context/placement/usage) are:
Create a base type with (abstract="true" to prevent it from being used directly)
Note: the ref attribute replaces the name attribute for elements defined elsewhere
<xs:complexType name="CustomerType" abstract="true" >
<xs:sequence>
<xs:element ref="cust:FirstName" />
<xs:element ref="cust:LastName" />
<xs:element ref="cust:PhoneNumber" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="customerID" type="xs:integer" />
</xs:complexType>
Create two or more derived types by extending or restricting the base type
<xs:complexType name="MandatoryPhoneCustomerType" >
<xs:complexContent>
<xs:restriction base="cust:CustomerType">
<xs:sequence>
<xs:element ref="cust:FirstName" />
<xs:element ref="cust:LastName" />
<xs:element ref="cust:PhoneNumber" minOccurs="1" />
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
and
<xs:complexType name="AddressableCustomerType" >
<xs:complexContent>
<xs:extension base="cust:CustomerType">
<xs:sequence>
<xs:element ref="cust:Address" />
<xs:element ref="cust:City" />
<xs:element ref="cust:State" />
<xs:element ref="cust:Zip" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
Reference the base type in an element
<xs:element name="Customer" type="cust:CustomerType" />
In your instance XML document, specify the specific derived type as an xsi:type attribute
<cust:Customer customerID="12345" xsi:type="cust:MandatoryPhoneCustomerType" >
<cust:FirstName>Dare</cust:FirstName>
<cust:LastName>Obasanjo</cust:LastName>
<cust:PhoneNumber>425-555-1234</cust:PhoneNumber>
</cust:Customer>
or:
<cust:Customer customerID="67890" xsi:type="cust:AddressableCustomerType" >
<cust:FirstName>John</cust:FirstName>
<cust:LastName>Smith</cust:LastName>
<cust:Address>2001</cust:Address>
<cust:City>Redmond</cust:City>
<cust:State>WA</cust:State>
<cust:Zip>98052</cust:Zip>
</cust:Customer>
Yes, XSD can handle this. I generated this schema from Visual Studio 2008 (much faster than doing it by hand) and it will do what you're looking for:
<?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="items">
<xs:complexType>
<xs:sequence>
<xs:element name="group">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="item">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="data">
<xs:complexType>
<xs:sequence>
<xs:element name="group">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="customer">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="item">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="count" type="xs:unsignedByte" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="place" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

Resources