Leverage XSD annotations to build richer XML schema


In the service-oriented enterprise IT landscape, XML schema is the default language used to describe information models. Products and IT departments today care less about the domain-model, and view the systems as a collection of services, orchestrated to perform business functions. And how do you describe and document your services? Unlike domain-models which can be expressed in very well in-terms of UML class diagrams, ER diagrams there is not a popular formal notation to design or describe your service portfolio.

This gap is partly addressed by the several SOA governance tools which govern the lifecycle of service definitions and implementation. You can use these tools to capture information such as the status, usages, dependencies, SLAs, security aspects associated with a service along with a broad description of the service itself.

While this is extremely important and needed, it does not solve the entire problem. Somewhat neglected in this solution is the description the service request and response objects. It is a common assumption that since services are described using WSDL and therefore XML Schema and eventual XML – the messages are self-describing. But more often than not the XML Schema definition of the XML message does not convey enough information about the message.

How do you use XML schema to convey conditional composition of a message, what each specific element means, how it maps to existing terms/concepts in the business model, business validation logic applicable on elements etc?  For example consider the following XML schema

<xsd:element name=”Address”>
<xsd:complexType>
<xsd:element name=”Line1″ type=”xsd:string”/>
<xsd:element name=”Line2″ type=”xsd:string”/>
<xsd:element name=”Line3″ type=”xsd:string”/>
<xsd:element name=”City” type=”xsd:string”/>
<xsd:element name=”District” type=”xsd:string”/>
<xsd:element name=”State” type=”xsd:string”/>
<xsd:element name=”Region” type=”xsd:string”/>
<xsd:element name=”Country” type=”xsd:string”/>
<xsd:element name=”Zipcode” type=”xsd:string”/>
<xsd:element name=”pincode” type=”xsd:string”/>
<xsd:element name=”landmark” type=”xsd:string”/>
<xsd:element name=”latitude” type=”xsd:numeric”/>
<xsd:element name=”longitude” type=”xsd:numeric”/>
</xsd:complexType>
</xsd:element>

The above is a fairly decent  description of a “Address” element which can be applied to most geographies. Now let us say a CreateCustomer service uses this address element as part of a NewCustomer message.

<xsd:element name=”Customer”>
<xsd:complexType>
<xsd:element name=”name” type=”xsd:string”/>
<xsd:element name=”age” type=”xsd:integer”/>
<xsd:element ref=”Address”/>
</xsd:element>

Great. At this point I seem to know what I should do to create a customer. Use a request with the customer name, age and address details. A simple as that.  But now when we take a look at the address schema – which of the Address elements need to be populated to correctly create a customer? A US address would need a ZIPCode, Indian addresses need a PIN code, but yet it is optional if you enter City, District and Line3 (which should be Street information btw for Indian addresses.). How do I inform the service consumer all this? A PDF user-manual would be needed here. WSDL + XML Schema does not tell the poor programmer everything he needs to get the job done well enough.

One approach to make your schema’s more powerful – is using comments and annotations. A XML schema document with comments

<xsd:element name=”Address”>
<xsd:complexType>
<xsd:element name=”Line1″ type=”xsd:string”/>
<xsd:element name=”Line2″ type=”xsd:string”/>
<!– should contain “Street name” in India –>
<xsd:element name=”Line3″ type=”xsd:string”/>
<xsd:element name=”City” type=”xsd:string”/>
<xsd:element name=”District” type=”xsd:string”/>
<!– only valid 2 letter codes for US address, full state name for indian –>
<xsd:element name=”State” type=”xsd:string”/>
<xsd:element name=”Region” type=”xsd:string”/>
<xsd:element name=”Country” type=”xsd:string”/>
<!– must for US, UK, Britain –>
<xsd:element name=”Zipcode” type=”xsd:string”/>
<!– needed for indian addresses if city/state/description are left empty –>
<xsd:element name=”pincode” type=”xsd:string”/>
<xsd:element name=”landmark” type=”xsd:string”/>
<xsd:element name=”latitude” type=”xsd:numeric”/>
<xsd:element name=”longitude” type=”xsd:numeric”/>
</xsd:complexType>
</xsd:element>

While the above comments are very helpful, it is a very flaky solution.

A better approach would be to leverage XSD annotations which can be used to specify additional meta-data about the schema elements. For example,

<xsd:element name=”Line3″ type=”xsd:string”>
<xsd:annotation>
<xsd:documentation>3rd address line. Do not use this element if more specific element e.g. State, Country, City is already available. Use only for free-text identification. </xsd:documentation>
</xsd:annotation>
</xsd:element>

However, while this seems more structured, it still degenerates to being equivalent of xml comments in the schema file. It is left to the schema author to describe the rules well enough, and since the documentation is embedded in the schema itself, it becomes very difficult to keep the business rules current – considering the schema is going to be copied and used in multiple places.

A better approach is to use the xsd:appInfo element within the xsd:annotation. The appInfo element can contain a well-defined XML and can be used to provide a more structure meta-data to the XML schema user. In addition the contents of the appInfo element can be made available to the application which is processing  XML instances based on the schema – and this can be very useful.

You can refer for example to business rules defined in say an external rules repository

<xsd:element name=”Line3″ type=”xsd:string”>
<xsd:annotation>
<xsd:appInfo>
<cust:RuleSet xmlns:cust=”http://myenterprise/it9/rule-engine”&gt;
<cust:RuleID>rules:crm:address:7</cust:RuleID>
<cust:RuleID>rules:crm:address:8</cust:RuleID>
<cust:RuleID>rules:crm:address:15</cust:RuleID>
</cust:RuleSet>
</xsd:appInfo>
</xsd:annotation>
</xsd:element>

Alternatively, you can use a language such as schematron to define additional constraint / validation logic.

<xsd:element name=”Line1″>
<xsd:annotation>
<xsd:appinfo>
<sch:pattern name=”validateLine1″>
<sch:rule context=”ns1:Address”>
<sch:assert test=”/ns1:Line1″>
Line1 is must
</sch:assert>
</sch:rule>
</sch:pattern>

Along with validation, business rule logic – the xsd:appInfo element can be extremely useful to capture mapping information in XML Schema. For example,

<xsd:element name=”Line3″ type=”xsd:string”>
<xsd:annotation>
<xsd:appInfo>
<cust:Mappings xmlns:cust=”http://myenterprise/mapping/v10.4″&gt;
<cust:Map cust:mappingContext=”SiebelCRM”>
<cust:MapTarget>ADDRESS_TBL.LINE_THREE</cust:MapTarget>
</cust:Map>
<cust:Map cust:mappingContext=”Salesforce_Address”>
<cust:MapTarget>/sf:addressdetails/sf:addresslinethree</cust:MapTarget>
</cust:Map>
</cust:Mappings>
</xsd:appInfo>
</xsd:annotation>

Having made this case, it needs to be mentioned that there is limited support to the xsd:annotation element in most schema design tools. For example none of the schema authoring tools provide a feature to associate pre-defined templates for annotations.  Without such support and lack of ability to verify that the appInfo elements are correctly defined for a project’s requirement – there are challenges in using this approach.

Few links/references on xsd:annotations and xsd:appinfo

http://www.w3schools.com/schema/el_appinfo.asp
http://www.w3schools.com/schema/el_annotation.asp

Advertisements

About saratnathb

Building SOA solutions using Oracle Fusion Middleware technology stack.
This entry was posted in Uncategorized and tagged , , . Bookmark the permalink.

2 Responses to Leverage XSD annotations to build richer XML schema

  1. Pingback: Sarat Buddhiraju's Blog

  2. Pingback: Semantic web-service descriptions using OWL-S | Sarat Buddhiraju's Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s