Need help creating XML file from XSD schema - xsd

I am learning to work with XML schemas.
I want to create an XML file based on the "address.xsd" schema file :
"address.xsd"
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema
elementFormDefault="qualified"
targetNamespace="com.namespace.address"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="AddressDetails">
<xs:sequence>
<xs:element name="building" type="xs:string" />
<xs:element name="street" type="xs:string" />
<xs:element name="city" type="xs:string" />
<xs:element name="country" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
address.xml
<?xml version="1.0" encoding="utf-8"?>
<a:AddressDetails
xmlns:a="com.namespace.address"
xsi:schemaLocation="D:/Prac/XML/address.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
<a:building>Crosswords</a:building>
<a:street>MainStreet</a:street>
<a:city>LA</a:city>
<a:country>USA</a:country>
</a:AddressDetails>
Iam not getting why this is not working.

Actually XSD is used to validate xml not for XML generation

Ok, i have figured out the problem. There was some problem with the namespaces. Here i am posting the "address.xsd" schema file along with the valid "address.xml".
address.xsd
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema elementFormDefault="qualified" targetNamespace="com.namespace.address" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="AddressDetails">
<xs:sequence>
<xs:element name="building" type="xs:string" />
<xs:element name="street" type="xs:string" />
<xs:element name="city" type="xs:string" />
<xs:element name="country" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:element name="address" xmlns:q1="com.namespace.address" type="q1:AddressDetails" />
</xs:schema>
address.xml
<?xml version="1.0" encoding="utf-8"?>
<a:address xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="com.namespace.address address.xsd" xmlns:a="com.namespace.address">
<a:building>Crosswords</a:building>
<a:street>Main Street</a:street>
<a:city>LA</a:city>
<a:country>USA</a:country>
</a:address>

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>

cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found

I am trying to understand <any> element in xsd. I had two xsds.
Book Catalogue.xsd
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com" xmlns="http://www.w3schools.com"
elementFormDefault="qualified">
<xs:element name="BookCatalogue">
<xs:complexType>
<xs:sequence>
<xs:element name="Book" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Title" type="xs:string" />
<xs:element name="Author" type="xs:string" />
<xs:element name="Date" type="xs:string" />
<xs:element name="ISBN" type="xs:string" />
<xs:element name="Publisher" type="xs:string" />
<xs:any namespace="##any" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Reviewer.xsd
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com" xmlns="http://www.w3schools.com"
elementFormDefault="qualified">
<xs:element name="Reviewer">
<xs:complexType>
<xs:sequence>
<xs:element name="Name">
<xs:complexType>
<xs:sequence>
<xs:element name="First" type="xs:string" />
<xs:element name="Last" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
But if i validate the below xml based on above xsd, i am getting cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'p:Reviewer'. error. Does both xsd file should not be in same namespace?
<?xml version="1.0" encoding="UTF-8"?>
<pr:BookCatalogue xmlns:pr="http://www.w3schools.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3schools.com AddRequest.xsd ">
<pr:Book>
<pr:Title>pr:Title</pr:Title>
<pr:Author>pr:Author</pr:Author>
<pr:Date>pr:Date</pr:Date>
<pr:ISBN>pr:ISBN</pr:ISBN>
<pr:Publisher>pr:Publisher</pr:Publisher>
<p:Reviewer xmlns:p="http://www.w3schools.com"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3schools.com Children.xsd ">
<p:Name>
<p:First>p:First</p:First>
<p:Last>p:Last</p:Last>
</p:Name>
</p:Reviewer>
</pr:Book>
</pr:BookCatalogue>
Two options...
Option One: If you do not want to have to have the definition of p:Reviewer present, add processContents="lax" to your xs:any element:
<xs:any namespace="##any" minOccurs="0" processContents="lax"/>
Per XML Schema Part 0: Primer Second Edition:
The lax value of the processContents attribute instructs an XML
processor to validate the element content on a can-do basis: It will
validate elements and attributes for which it can obtain schema
information, but it will not signal errors for those it cannot obtain
any schema information.
See also XML Validation in Java: processContents=“lax” seems not to work correctly.
You should also carefully adjust your xsi:schemaLocation values to point to the actual filename of each XSD for each namespace in play. Here is your XML instance with the changes that I made:
<?xml version="1.0" encoding="UTF-8"?>
<pr:BookCatalogue
xmlns:pr="http://www.w3schools.com"
xmlns:p="http://www.w3schools.com/1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3schools.com BookCatalogue.xsd http://www.w3schools.com/1 Reviewer.xsd">
<pr:Book>
<pr:Title>pr:Title</pr:Title>
<pr:Author>pr:Author</pr:Author>
<pr:Date>pr:Date</pr:Date>
<pr:ISBN>pr:ISBN</pr:ISBN>
<pr:Publisher>pr:Publisher</pr:Publisher>
<p:Reviewer>
<p:Name>
<p:First>p:First</p:First>
<p:Last>p:Last</p:Last>
</p:Name>
</p:Reviewer>
</pr:Book>
</pr:BookCatalogue>
Note: Make sure that the targetNamespace in Review.xsd matches what's declared for it in BookCatalogue.xml's xsi:schemaLocation attribute.
Option Two: If you do want to insist that the definition of p:Reviewer be present, just make the above changes to be sure that Review.xsd can be found per the xsi:schemaLocation mechanism. No processContents setting is required; it defaults to strict.

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>

Override minoccurs of an element from parent xsd

is it possible to override the minOccurs/maxOccurs attributes of an element in the parent xsd? we can easily extend the parent xsd and create a new xsd with different namespace, but am trying to override with same parent namespace.
Lets say we have an xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:cust="http://test.com/schema/cust" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://test.com/schema/cust" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:complexType name="customer-type">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:element name="hobby" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:element name="customer" type="cust:customer-type"/>
</xs:schema>
can i create extension/restriction of above xsd with same namespace which will restrict/change the <cust:hobby> minOccurs to be 1?
Okay, i was complicating the solution. Before this i was trying to use override function in xml 1.0 which is available only from xml 1.1.
A simple redefine would do the trick:
If the name of your base xsd is cust.xsd then the below redefinition overrides the minOccurs of "hobby" element to 1.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:cust="http://test.com/schema/cust" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://test.com/schema/cust" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:redefine schemaLocation="cust.xsd">
<xs:complexType name="customer-type">
<xs:complexContent>
<xs:restriction base="cust:customer-type">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:element name="hobby" type="xs:string" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:redefine>
</xs:schema>

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..

Resources