Skip to Content
Technical Articles

Tips & tricks for creating XSD schema’s for intermediate processing

In lots of projects I encounter situations that require a different approach to processing the data than sending a single message through a mapping. Often a new JSON/XML data model is required to transform data prior for sending it to the receiver system. These schema’s act as intermediate mapping structures and not as actual sender system data structures.

In these cases I often generate an XSD based on the object and data required. In this blog I will outline some tips & tricks I keep in mind during this process.

XSD schema generation

Most of the time I just start writing the desired XML data from scratch and then use a tool like freeformatter to generate the XSD. Often these generated XSD are not very precise in iterative structures and data types, therefore I always apply the following tips:

Avoid sequence in iterative structure when dealing with JSON data

In case of JSON input data do not use xs:sequence for iterative structures. JSON objects are not as strict in ordering as XML, I like to use xs:choice with maxOccurs=”unbounded” to relax this requirement and make field optional at the same time. More information can be found here.

Keep it simple

In order to have an intermediate mapping structure stick to elements as much as possible. I usually use attributes only for an identifier. Additionally, I keep the elements optional as much as possible especially in JSON situations. For typing I try to keep everything string based, If you have to apply scripting or other operations during mapping time then you do not get into conversion problems.

Validate required data

If you have data that is absolutely required to be available or to have a specific format use the XML validator to invalidate incoming data. I often write my own set of restrictions either based on validating a type or restricting data on an enumeration. More information can be found here, I use this as reference when developing.

Add a root node

If you have to convert between XML and JSON in the processing of the data it is recommended to add a root node to the XSD you are using. Especially in JSON to XML conversion there can be problems since JSON does not require a single parent node opposed to XML. Additionally, if you have a single object XSD with a root node it is easier to make the object iterative and keep the same structure.  More information about conversion possibilities can be found in the message transformers documentation.

Fruit shipment example

The fruit shipment example was created to do additional testing on parallel processing in CPI. This schema consists of shipment nodes containing trucks with pallets of fruit. Using this level of nesting enabled me to apply selection and filtering on different levels in order to get the data ordering required. Using the id attributes enabled me to quickly select specific nodes with xpath or gpath.

In this case I choose to have the XSD to contain sequence data because there are just a few elements and the test cases used did not require JSON conversion and processing.

Example data:

<?xml version="1.0" encoding="UTF-8"?>
<root>
	<shipment id="shipment1"> 
		<truck id="11-aa-11">
			<pallet>
				<content>banana</content>
				<count>22</count>
			</pallet>
			<pallet>
				<content>pear</content>
				<count>220</count>
			</pallet>
			<pallet>
				<content>apple</content>
				<count>220</count>
			</pallet>
			<pallet>
				<content>orange</content>
				<count>220</count>
			</pallet>
		</truck>
	</shipment>
</root>

 

XSD:

<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="shipment">
					<xs:complexType>
						<xs:sequence>
							<xs:element name="truck" maxOccurs="unbounded" minOccurs="0">
								<xs:complexType>
									<xs:sequence>
										<xs:element name="pallet" maxOccurs="unbounded" minOccurs="0">
											<xs:complexType>
												<xs:sequence>
													<xs:element name="content">
														<xs:simpleType>	
															<xs:restriction base="xs:token">
																<xs:enumeration value="apple"/>
																<xs:enumeration value="pear"/>
																<xs:enumeration value="orange"/>
																<xs:enumeration value="banana"/>
															</xs:restriction>
														</xs:simpleType>
													</xs:element>
													<xs:element type="xs:short" name="count"/>
												</xs:sequence>
											</xs:complexType>
										</xs:element>
									</xs:sequence>
									<xs:attribute type="xs:string" name="id"/>
								</xs:complexType>
							</xs:element>
						</xs:sequence>
						<xs:attribute type="xs:string" name="id"/>
					</xs:complexType>
				</xs:element>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
</xs:schema>

 

WSDL:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
	xmlns:tns="http://www.example.org/fruitshipment/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
	xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="fruitshipment"
	targetNamespace="http://www.example.org/fruitshipment/">
	<wsdl:types>
		<xsd:schema targetNamespace="http://www.example.org/fruitshipment/">
			<xsd:element name="processFruitShipment">
				<xsd:complexType>
					<xsd:sequence>
						<xsd:element name="shipment">
							<xsd:complexType>
								<xsd:sequence>
									<xsd:element name="truck" maxOccurs="unbounded"
										minOccurs="0">
										<xsd:complexType>
											<xsd:sequence>
												<xsd:element name="pallet" maxOccurs="unbounded"
													minOccurs="0">
													<xsd:complexType>
														<xsd:sequence>
															<xsd:element name="content">
																<xsd:simpleType>
																	<xsd:restriction base="xsd:token">
																		<xsd:enumeration value="apple" />
																		<xsd:enumeration value="pear" />
																		<xsd:enumeration value="orange" />
																		<xsd:enumeration value="banana" />
																	</xsd:restriction>
																</xsd:simpleType>
															</xsd:element>
															<xsd:element type="xsd:short" name="count" />
														</xsd:sequence>
													</xsd:complexType>
												</xsd:element>
											</xsd:sequence>
											<xsd:attribute type="xsd:string" name="id" />
										</xsd:complexType>
									</xsd:element>
								</xsd:sequence>
								<xsd:attribute type="xsd:string" name="id" />
							</xsd:complexType>
						</xsd:element>
					</xsd:sequence>
				</xsd:complexType>
			</xsd:element>
			<xsd:element name="processFruitShipmentResponse">
				<xsd:complexType>
					<xsd:sequence>
						<xsd:element name="status" type="xsd:string" />
					</xsd:sequence>
				</xsd:complexType>
			</xsd:element>
		</xsd:schema>
	</wsdl:types>
	<wsdl:message name="processFruitShipmentRequest">
		<wsdl:part element="tns:processFruitShipment" name="parameters" />
	</wsdl:message>
	<wsdl:message name="processFruitShipmentResponse">
		<wsdl:part element="tns:processFruitShipmentResponse" name="parameters" />
	</wsdl:message>
	<wsdl:portType name="fruitshipment">
		<wsdl:operation name="processFruitShipment">
			<wsdl:input message="tns:processFruitShipmentRequest" />
			<wsdl:output message="tns:processFruitShipmentResponse" />
		</wsdl:operation>
	</wsdl:portType>
	<wsdl:binding name="fruitshipmentSOAP" type="tns:fruitshipment">
		<soap:binding style="document"
			transport="http://schemas.xmlsoap.org/soap/http" />
		<wsdl:operation name="processFruitShipment">
			<soap:operation
				soapAction="http://www.example.org/fruitshipment/processFruitShipment" />
			<wsdl:input>
				<soap:body use="literal" />
			</wsdl:input>
			<wsdl:output>
				<soap:body use="literal" />
			</wsdl:output>
		</wsdl:operation>
	</wsdl:binding>
	<wsdl:service name="fruitshipment">
		<wsdl:port binding="tns:fruitshipmentSOAP" name="fruitshipmentSOAP">
			<soap:address location="http://www.example.org/" />
		</wsdl:port>
	</wsdl:service>
</wsdl:definitions>
Be the first to leave a comment
You must be Logged on to comment or reply to a post.