XSD reusing nodes or duplication - xsd

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>

Related

what will be XSD structure for the following xml---

the following is my xml file.what will be XSD structure for the following xml?
<sell>
<product>
<description></description>
<details>
<name></name>
<cost></cost>
</details>
</product>
</sell>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="sell">
<xs:complexType>
<xs:sequence>
<xs:element name="product">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="description"/>
<xs:element name="details">
<xs:complexType>
<xs:sequence>
<xs:element type="xs:string" name="name"/>
<xs:element type="xs:string" name="cost"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Obtained from http://www.freeformatter.com/xsd-generator.html

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 Required Elements with specific child elements (Multiple Definitions with different types)

All, I have an XML doc which I don't control for which I need to create an xsd to validate. The XML doc has multiple transaction types, some of which are required a specific number of times, and some aren't. the parent element is simply <transaction>, the child element can be either a <ControlTransaction> or a <RetailTransaction>. The issue is that I need to require a <transaction> to exists with a <ControlTransaction> with a <ReasonCode> element having a value of "Register Open" and another with a value of "Register Close" as follows:
<?xml version="1.0" encoding="UTF-8"?>
<RegisterDay xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:cp="urn:register">
<Transaction>
<SequenceNumber>1</SequenceNumber>
<ControlTransaction>
<ReasonCode>Register Open</ReasonCode>
</ControlTransaction>
</Transaction>
<Transaction>
<SequenceNumber>2</SequenceNumber>
<RetailTransaction>
...stuff..
<Total>9.99</Total>
</RetailTransaction>
</Transaction>
<Transaction>
<SequenceNumber>3</SequenceNumber>
<ControlTransaction>
<ReasonCode>Register Close</ReasonCode>
</ControlTransaction>
</Transaction>
</RegisterDay>
My best attempt is to use types in my schema, but get "Elements with the same name and same scope must have the same type". I don't know how to get around this.
<?xml version="1.0"?>
<xs:schema
xmlns:cp="urn:register"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
attributeFormDefault="unqualified"
elementFormDefault="qualified">
<xs:element name="RegisterDay">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="Transaction" type="TransactionRegisterOpen_type"/>
<xs:element minOccurs="1" maxOccurs="unbounded" name="Transaction" type="RetailTransaction_type"/>
<xs:element minOccurs="1" maxOccurs="1" name="Transaction" type="TransactionRegisterClose_type"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="RegisterOpen_type">
<xs:restriction base="xs:string">
<xs:pattern value="Register Open"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="RegisterClose_type">
<xs:restriction base="xs:string">
<xs:pattern value="Register Close"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="TransactionRegisterOpen_type">
<xs:sequence>
<xs:element name="SequenceNumber" type="xs:unsignedShort"/>
<xs:element name="ControlTransaction">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" name="ReasonCode" type="RegisterOpen_type"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="TransactionRegisterClose_type">
<xs:sequence>
<xs:element name="SequenceNumber" type="xs:unsignedShort"/>
<xs:element name="ControlTransaction">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" name="ReasonCode" type="RegisterClose_type"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="RetailTransaction_type">
<xs:sequence>
<xs:element name="SequenceNumber" type="xs:unsignedShort"/>
<xs:element name="ControlTransaction">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" name="Total" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
Has anyone run into this and/or have any suggestions? I'm pretty much stumped.
Perhaps with enumeration ?
<?xml version="1.0"?>
<xs:schema
xmlns:cp="urn:register"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
attributeFormDefault="unqualified"
elementFormDefault="qualified"
targetNamespace="urn:register">
<xs:element name="RegisterDay">
<xs:complexType>
<xs:sequence>
<xs:element
minOccurs="1"
maxOccurs="unbounded"
name="Transaction"
type="cp:TypeTransaction"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="TypeTransaction">
<xs:sequence>
<xs:element name="SequenceNumber" type="xs:unsignedShort"/>
<xs:choice>
<xs:element name="RetailTransaction"/>
<xs:element name="ControlTransaction">
<xs:complexType>
<xs:sequence>
<xs:element name="ReasonCode">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Register Open"/>
<xs:enumeration value="Register Close"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:schema>

JAXB Error, sample xsd docs

I'm getting a JAXB errors when I run "xjc -p foo.bar bmw.xsd":
[ERROR] A class/interface with the same name "foo.bar.Fault" is already in use.
line 16 of bmw.xsd
[ERROR] (Relevant to above error) another one is generated from here.
line 26 of abc.xsd
Is it related to the two 'fault' elements clashing? If so, what do I do to fix?
bmw.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://foo.com/bmw" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:bmw="http://foo.com/bmw">
<xs:import namespace="http://schemas.xmlsoap.org/soap/envelope/" schemaLocation="abc.xsd"/>
<xs:element name="rule">
<xs:complexType>
<xs:sequence>
<xs:element ref="bmw:customer"/>
<xs:element ref="bmw:schemaName"/>
<xs:element ref="bmw:schemaVersion"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="customer" type="xs:integer"/>
<xs:element name="schemaName" type="xs:NCName"/>
<xs:element name="schemaVersion" type="xs:decimal"/>
<xs:element name="fault">
<xs:complexType>
<xs:sequence>
<xs:element ref="bmw:faultcode"/>
<xs:element ref="bmw:faultstring"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="faultcode" type="xs:integer"/>
<xs:element name="faultstring" type="xs:string"/>
</xs:schema>
abc.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://schemas.xmlsoap.org/soap/envelope/" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:bmw="http://foo.com/bbs">
<xs:import namespace="http://foo.com/bmw" schemaLocation="bmw.xsd"/>
<xs:element name="Envelope">
<xs:complexType>
<xs:sequence>
<xs:element ref="env:Header"/>
<xs:element ref="env:Body"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Header">
<xs:complexType>
<xs:sequence>
<xs:element ref="bmw:rule"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Body">
<xs:complexType>
<xs:sequence>
<xs:element ref="env:Fault"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Fault">
<xs:complexType>
<xs:sequence>
<xs:element ref="bmw:fault"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
You have a couple of options when resolving the name conflict.
Option #1 - Schema Annotation
You can annotate the XML schema to resolve the name conflict:
<xs:element name="Fault">
<xs:annotation>
<xs:appinfo>
<jaxb:class name="Fault2" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element ref="bmw:fault"/>
</xs:sequence>
</xs:complexType>
</xs:element>
abc.xsd
Refer to the schema annotation on the "Fault" element.
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified" targetNamespace="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:bmw="http://foo.com/bbs"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.1">
<xs:import namespace="http://foo.com/bmw" schemaLocation="bmw.xsd" />
<xs:element name="Envelope">
<xs:complexType>
<xs:sequence>
<xs:element ref="env:Header" />
<xs:element ref="env:Body" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Header">
<xs:complexType>
<xs:sequence>
<xs:element ref="bmw:rule"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Body">
<xs:complexType>
<xs:sequence>
<xs:element ref="env:Fault" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Fault">
<xs:annotation>
<xs:appinfo>
<jaxb:class name="Fault2" />
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element ref="bmw:fault"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Option #2 - External Bindings File
Instead of modifying the XML schema you can also use an external bindings file:
bindings.xml
<jaxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<jaxb:bindings schemaLocation="abc.xsd">
<jaxb:bindings node="//xs:element[#name='Fault']">
<jaxb:class name="Fault2"/>
</jaxb:bindings>
</jaxb:bindings>
</jaxb:bindings>
The xjc command would be:
xjc -d out -b bindings.xml abc.xsd
Package Name
To control the package name you can either pass it as a parameter to the XJC command:
xjc -d out -b bindings.xml -p com.foo.bar abc.xsd
Or amend the bindings file.
Yes, your error is related to the clash. You can fix this with a customized binding. A customized binding is a way of telling JAXB to do something other than what it naturally would do. Try looking into the class tag in an external binding file if you cannot annotate the XSD yourself.

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.

Resources