How to use a binding file with source generation Intended Audience Background The Supply Chain XSD Binding file? - IT IS REQUIRED! References
Intended Audience
Anyone who wants to use a binding file with the Castor XML
source generator. This document discusses various main concepts
in the context of a non-trivial real word example, and intends to
help people to get familiar with the basic concepts and discusses
some implementation details.
The example given describes the steps required to build a binding file
that helps users to overcome typical problems related to the use of
more complex XML Schemas.
Background
Two companies wish to trade with each other using a Supply Chain messaging
system. This system sends and receives Purchase Orders and Order Receipt
messages. After many months of discussion they have finally decided upon the
structure of the Version 1.0 of their message XSD and both are presently
developing solutions for it. One of the companies decides to use Java and
Castor XML supprt for (un)marshalling and Castor's code generator to accelerate
their development process.
The Supply Chain XSD
supplyChainV1.0.xsd |
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:element name="Data">
<xs:annotation>
<xs:documentation>This section contains the supply chain message
data</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:choice>
<xs:element name="PurchaseOrder">
<xs:complexType>
<xs:sequence>
<xs:element name="LineItem" type="LineItemType" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="OrderNumber" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="OrderReceipt">
<xs:complexType>
<xs:sequence>
<xs:element name="LineItem" type="ReceiptLineItemType" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="OrderNumber" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:complexType name="SkuType">
<xs:annotation>
<xs:documentation>Contains Product Identifier</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="Number" type="xs:integer"/>
<xs:element name="ID" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ReceiptSkuType">
<xs:annotation>
<xs:documentation>Contains Product Identifier</xs:documentation>
</xs:annotation>
<xs:complexContent>
<xs:extension base="SkuType">
<xs:sequence>
<xs:element name="InternalID" type="xs:string"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="LineItemType">
<xs:sequence>
<xs:element name="Sku" type="SkuType"/>
<xs:element name="Value" type="xs:double"/>
<xs:element name="BillingInstructions" type="xs:string"/>
<xs:element name="DeliveryDate" type="xs:date"/>
<xs:element name="Number" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ReceiptLineItemType">
<xs:sequence>
<xs:element name="Sku" type="ReceiptSkuType"/>
<xs:element name="Value" type="xs:double"/>
<xs:element name="PackingDescription" type="xs:string"/>
<xs:element name="ShipDate" type="xs:dateTime"/>
<xs:element name="Number" type="xs:integer"/>
</xs:sequence>
</xs:complexType>
</xs:schema> |
|
Binding file? - IT IS REQUIRED!
If you run the Castor CodeGenerator on the above XSD you end up with
the following set of classes. [You also get lots of warning messages with
the present 0.99 version.]
Data.java
DataDescriptor.java
LineItem.java
LineItemDescriptor.java
LineItemType.java
LineItemTypeDescriptor.java
OrderReceipt.java
OrderReceiptDescriptor.java
PurchaseOrder.java
PurchaseOrderDescriptor.java
ReceiptLineItemType.java
ReceiptLineItemTypeDescriptor.java
ReceiptSkuType.java
ReceiptSkuTypeDescriptor.java
Sku.java
SkuDescriptor.java
SkuType.java
SkuTypeDescriptor.java |
|
The problem here is that there are two different elements with the same
name in different locations in the XSD. This causes a java code generation
conflict. Castor uses the element name as the name of the class. So the
second class generated for the LineItem definition, which is different than
the first, overwrites the first class generated.
A binding file is therefore necessary to help the Castor code generator
differentiate between these generated classes. [i.e. You can 'bind' an
element in the XSD to a differently named class file that you want to
generate. Thus keeping different elements seperate]
Tip: | The warning messages for Castor 0.99+ are very usefull in assisting you
in your creation of the binding file. For the example the warning messages for the example are;
Warning: A class name generation conflict has occured between element '/Data/OrderReceipt/LineItem' and element '/Data/PurchaseOrder/LineItem'. Please use a Binding file to solve this problem.Continue anyway [not recommended] (y|n|?)y
Warning: A class name generation conflict has occured between element '/Data/OrderReceipt/LineItem' and element '/Data/PurchaseOrder/LineItem'. Please use a Binding file to solve this problem.Continue anyway [not recommended] (y|n|?)y
Warning: A class name generation conflict has occured between element '/Data/OrderReceipt/LineItem' and element '/Data/PurchaseOrder/LineItem'. Please use a Binding file to solve this problem.Continue anyway [not recommended] (y|n|?)y
Warning: A class name generation conflict has occured between element 'complexType:ReceiptLineItemType/Sku' and element 'complexType:LineItemType/Sku'. Please use a Binding file to solve this problem.Continue anyway [not recommended] (y|n|?)y
Warning: A class name generation conflict has occured between element 'complexType:ReceiptLineItemType/Sku' and element 'complexType:LineItemType/Sku'. Please use a Binding file to solve this problem.Continue anyway [not recommended] (y|n|?)y
Warning: A class name generation conflict has occured between element 'complexType:ReceiptLineItemType/Sku' and element 'complexType:LineItemType/Sku'. Please use a Binding file to solve this problem.Continue anyway [not recommended] (y|n|?)y
|
|
The following binding file definition will overcome the naming issues for
the generated classes.
binding.xml |
<binding xmlns="http://www.castor.org/SourceGenerator/Binding"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.castor.org/SourceGenerator/Binding
C:\\Castor\\xsd\\binding.xsd"
defaultBinding="element">
<elementBinding name="/Data/PurchaseOrder/LineItem">
<java-class name="PurchaseOrderLineItem"/>
</elementBinding>
<elementBinding name="/Data/OrderReceipt/LineItem">
<java-class name="OrderReceiptLineItem"/>
</elementBinding>
<elementBinding name="complexType:ReceiptLineItemType/Sku">
<java-class name="OrderReceiptSku"/>
</elementBinding>
<elementBinding name="complexType:LineItemType/Sku">
<java-class name="PurchaseOrderSku"/>
</elementBinding>
</binding> |
|
Things to notice in the above binding.xml file are that the name path used
is relative to the root of the XSD NOT the root of the target XML. Also notice
that the two complex types have the "complexType:" prefix to identify them, and
then the name path relative to the root of the XSD.
The new list of generated classes is:
Data.java
DataDescriptor.java
LineItem.java
LineItemDescriptor.java
LineItemType.java
LineItemTypeDescriptor.java
OrderReceipt.java
OrderReceiptDescriptor.java
OrderReceiptLineItem.java
OrderReceiptLineItemDescriptor.java
OrderReceiptSku.java
OrderReceiptSkuDescriptor.java
PurchaseOrder.java
PurchaseOrderDescriptor.java
PurchaseOrderLineItem.java
PurchaseOrderLineItemDescriptor.java
PurchaseOrderSku.java
PurchaseOrderSkuDescriptor.java
ReceiptLineItemType.java
ReceiptLineItemTypeDescriptor.java
ReceiptSkuType.java
ReceiptSkuTypeDescriptor.java
Sku.java
SkuDescriptor.java
SkuType.java
SkuTypeDescriptor.java |
|
The developers can now use these generated classes with Castor to
(un)marshal the supply chain messages sent by their business partner.
References
|