Writing a schema for my simple tree like xml data - xsd

Please let me know how to write a schema for my simple xml data.
It is like the following example. Where both of the 2 attributes are of integer type,
or of the most efficient data type.
<node id="1" parent="">
<node id="2" parent="1">
<node id="3" parent="2"></node>
<node id="4" parent="2"></node>
</node>
</node>
Thank you in advance.

I just generated this by dropping your sample XML onto http://www.flame-ware.com/products/xml-2-xsd/default.aspx
It looks pretty useful as a starting point?
<?xml version="1.0"?>
<!-- Generated using Flame-Ware Solutions XML-2-XSD v2.0 at http://www.flame-ware.com/Products/XML-2-XSD/ -->
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="node">
<xs:complexType>
<xs:sequence>
<xs:element ref="node" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="id" type="xs:string" />
<xs:attribute name="parent" type="xs:string" />
</xs:complexType>
</xs:element>
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="node" />
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>

Related

XSD - XNOR gate of 2 nodes

I trying to create a XSD which validates XML only if both nodes A and B exist or both does not exist (XNOR gate).
I have checked the internet, however, without any luck.
<root>
<A>a</A>
<B>b</B>
<C>c</C>
</root>
I have found a solution:
<?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" type="root"/>
<xs:complexType name="root">
<xs:sequence>
<xs:choice>
<xs:sequence>
<xs:element name="a" type="xs:string" />
<xs:element name="b" type="xs:string" />
</xs:sequence>
<xs:sequence></xs:sequence>
</xs:choice>
<xs:element name="c" type="xs:string" />
</xs:sequence>
</xs:complexType>

Unique element in XSD sequence

I'd like to have an XSD to valide an XML containing file elements with many aliases but each alias with a different value.
This is my XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<folder>
<files>
<fileList>
<file>
<title>Document1</title>
<fileAlias>
<alias>Alias1</alias>
<alias>Alias2</alias>
</fileAlias>
</file>
</fileList>
</files>
</folder>
The former XML is good because Alias1 != Alias2
How could I specify it in my XSD:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" version="1.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="folder" type="folderType" />
<xs:complexType name="folderType">
<xs:sequence>
<xs:element name="files" type="filesType" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="filesType">
<xs:sequence>
<xs:element name="fileList" type="fileListType" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="fileListType">
<xs:sequence>
<xs:element maxOccurs="unbounded" name="file" type="fileType" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="fileType">
<xs:sequence>
<xs:element name="title" type="xs:string" />
<xs:element name="fileAlias" type="fileAliasType" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="id" type="xs:string" />
<xs:attribute name="type" type="xs:int" />
</xs:complexType>
<xs:complexType name="fileAliasType">
<xs:sequence>
<xs:element maxOccurs="unbounded" name="alias" type="xs:string" minOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:schema>
I've tried with xsd:unique but I think is for attributes not for XML element text values.
If I understand well your need then xs:unique should be the right way. Following modification of fileType complex type should be enough.
<xs:complexType name="fileType">
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="fileAlias" type="fileAliasType" minOccurs="0" maxOccurs="unbounded">
<xs:unique name="alias_unique">
<xs:selector xpath="alias"/>
<xs:field xpath="."/>
</xs:unique>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:string"/>
<xs:attribute name="type" type="xs:int"/>
</xs:complexType>
This will validate
<?xml version="1.0" encoding="UTF-8"?>
<!--Sample XML file generated by XMLSpy v2013 sp1 (http://www.altova.com)-->
<folder xsi:noNamespaceSchemaLocation="unique.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<files>
<fileList>
<file id="String" type="0">
<title>String</title>
<fileAlias>
<alias>String1</alias>
<alias>String2</alias>
<alias>String3</alias>
</fileAlias>
</file>
</fileList>
</files>
</folder>
This won't
<?xml version="1.0" encoding="UTF-8"?>
<!--Sample XML file generated by XMLSpy v2013 sp1 (http://www.altova.com)-->
<folder xsi:noNamespaceSchemaLocation="unique.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<files>
<fileList>
<file id="String" type="0">
<title>String</title>
<fileAlias>
<alias>String1</alias>
<alias>String1</alias>
<alias>String3</alias>
</fileAlias>
</file>
</fileList>
</files>
</folder>

xsd choice for multiple elements

I would like my Xml file to look like the following
<root>
<name>a</name>
<age>23</age>
</root>
or
<root>
<empno>b<empno>
<designation>ase</designation>
</root>
is it possible to create a XML schema for the above using a "choice" indicator?something like below.
<xsd:element name="root">
<xsd:complexType>
<xsd:choice>
<xsd:element name="name"/>
<xsd:element name="age" />
or
<xsd:element name="empno"/>
<xsd:element name="designation" />
<xsd:choice>
</xsd:complexType>
<xsd:element>
Is it possible to do like this?
Yes, You are almost there.. just missing a sequence .. Since it's the set of fields you have to wrap them under sequence..
These sequence tags will be under <Choice> tag. Now either of these set of tags (Sequence) will be validated.
<?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" type="root"/>
<xs:complexType name="root">
<xs:choice>
<xs:sequence>
<xs:element name="empno" type="xs:string" />
<xs:element name="designation" type="xs:string" />
</xs:sequence>
<xs:sequence>
<xs:element name="name" type="xs:string" />
<xs:element name="age" type="xs:unsignedByte" />
</xs:sequence>
</xs:choice>
</xs:complexType>
</xs:schema>
-----------------------------------------------------------------------------------------
I would like to add one more suggestion here:
I observe that you use nested declarations .. like this:
<?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="trunk">
<xs:complexType>
<xs:sequence>
<xs:element name="branch1" type="xs:string"/>
<xs:element name="branch2" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="other" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Always prefer usage of Custom types! Like this:
<?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" type="root"/>
<xs:complexType name="root">
<xs:sequence>
<xs:element name="trunk" type="trunk"/>
<xs:element name="other" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="trunk">
<xs:sequence>
<xs:element name="branch1" type="xs:string"/>
<xs:element name="branch2" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
This improves readability and you can reuse the complexType/simpleType ..
hope it helps..

XSD Schema that JAXB would find acceptable

I have a REST XML response that has a chunk of data like this:
<tag>
<total-pages type="integer">5</total-pages>
<previous-page nil="true"></previous-page>
<next-page nil="true"></next-page>
<offset type="integer">5</offset>
</tag>
Now, sometimes the data can come back like this:
<tag>
<total-pages type="integer">5</total-pages>
<previous-page type="integer">0</previous-page>
<next-page type="integer">1</next-page>
<offset type="integer">5</offset>
</tag>
I have been trying to come up with a XSD schema structure that will account for both possibilities that would be acceptable to JAXB.
I have tried:
<tag>
<total-pages type="numeric-type" />
<previous-page type="numeric-type" />
<next-page type="numeric-type" />
<offset type="numeric-type" />
</tag>
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="xsd:integer">
<xsd:attribute type="xsd:string" name="type" use="optional">
<xsd:attribute type="xsd:boolean" name="nil" use="optional">
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
but JAXB blows up with an unmarshalling error.
Thoughts on what XSD schema structure I could use to account for the variability in the returning XML (I cannot change the XML, it is coming from a third-party which I have no control).
Thank you,
Perry
I've started by generating one XSD from your XML samples (two in your case):
<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="tag">
<xs:complexType>
<xs:sequence>
<xs:element name="total-pages">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:unsignedByte">
<xs:attribute name="type" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="previous-page">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="type" type="xs:string" use="optional" />
<xs:attribute name="nil" type="xs:boolean" use="optional" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="next-page">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="type" type="xs:string" use="optional" />
<xs:attribute name="nil" type="xs:boolean" use="optional" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="offset">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:unsignedByte">
<xs:attribute name="type" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
When you compare with your XSD, you'll notice the use of string instead of integer as the base type. Which explains why you have a problem with unmarshalling: an empty string is not a valid number.
If instead of "nil" you would get an xsi:nil attribute, the XSD would've been generated differently, i.e. it would've had nillable="true" for your elements.
Since you cannot change the XML, then you're stuck with the use of string; alternatively, you could create a union between an empty string and a numeric value... as to how that'll look in JAXB, you can try it...

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