XSLT Tools for XSD to CAM
The tools provided here allow you to extract and ingest various components from inside XSD schema and automatically generate the equivalent CAM template components.
They are designed to save you time if you have an existing XSD schema for your XML instances and want to apply those same rules in your CAM templates.
The tools are provided as a ZIP file with a readme instructions. The tools have been tested with Saxon 9.0 xslt processor in OxygenXML and Stylus Studio - but should run with other tools such as XMLSpy as well - or the Saxon 9.0 command line version.
The tools are also integrated in the jCAM Eclipse editor for CAM - available from here.
There is a schema expander tool for XSD include or import statements so if your XSD uses these you will need to run that first to produce an expanded result to use for the main generation process.
To download the ZIP file with the XSD 2 CAM utilities in it - click here.
Example of generated CAM template
This link shows you an example of the CAM rules generated from the OASIS EDXL schema. The original XSD is 291K while the equivalent CAM template is 90K.
EDXL example generated template
Example of generated XML instance
This link shows you an example of the XML created by the instance generator. This will produce zero errors when validated with the above CAM template. The generator is designed to help you create a conformance test suite to use with your CAM templates. The source XSLT for the instance generator is here. This generator uses the internal CXF format of the CAM template from the jCAM editor (can be exported from inside jCAM editor).
Valid EDXL test instance generated by XSD2CAM generator tool
Example of EDXL rules report from jCAM editor
The link here shows an example of the rules report output from jCAM editor from the generated CAM template. It shows how the CAM template provides documentation of the content handling rules from inside your XSD schema in a simple tabular report format that can then be visually inspected and verified.
XSLT for converting XSD documentation to CAM annotation details
Source code
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:as="http://www.oasis-open.org/committees/cam" xmlns:camed="http://jcam.org.uk/editor" exclude-result-prefixes="xs xsd" version="1.0">
<!-- Provided "as is" License: Creative Commons - http://creativecommons.org/licenses/by-sa/3.0/
Author: David RR Webber, February, 2008 -->
<!--
- Purpose : Extract XSD documentation into CAM template annotations
- Original : 02/20/2008
- Initials : drrw
- CAM ver : 1.1
- Description : Part of a set of tools to ease alignment of XSD based validations and documentation
- and CAM templates.
- 02/20/08 drrw Initial release
- 02/23/08 drrw Add parsing of attribute documentation
-->
<xsl:output indent="yes"/>
<xsl:template match="*">
<xsl:variable name="ns-prefix" ><xsl:value-of select="./@targetNamespace"/></xsl:variable>
<as:Extension xmlns:as="http://www.oasis-open.org/committees/cam" name="uk.org.jcam.camed.extensions.StructureAnnotations">
<xsl:for-each select="/"><!-- parses the entire XSD input -->
<xsl:call-template name="doIt">
<xsl:with-param name="this" select="."/> <xsl:with-param name="this-parent" select=""/> <xsl:with-param name="last-parent" select=""/>
</xsl:call-template>
</xsl:for-each>
</as:Extension>
</xsl:template>
<xsl:template name="doIt">
<xsl:param name="this"/> <xsl:param name="this-parent"/>
<xsl:param name="last-parent"/>
<xsl:if test="local-name($this/.) = 'element' or(local-name($this/.) = 'complexType')">
<xsl:if test="count(./xsd:annotation/xsd:documentation) > 0">
<xsl:element name="camed:annotation">
<xsl:attribute name="item">
<xsl:choose> <xsl:when test="count(./@name) > 0">/<xsl:value-of select="$last-parent"/>/asm1:<xsl:value-of select="./@name"/></xsl:when> <xsl:when test="count(./@ref) > 0">/<xsl:value-of select="$last-parent"/>/asm1:<xsl:value-of select="./@ref"/></xsl:when> <xsl:otherwise/> </xsl:choose>
</xsl:attribute> <camed:documentation type="Definition"><xsl:value-of select="./xsd:annotation/xsd:documentation"/></camed:documentation>
</xsl:element>
</xsl:if>
</xsl:if> <xsl:if test="local-name($this/.) = 'attribute'">
<xsl:if test="count(./xsd:annotation/xsd:documentation) > 0">
<xsl:element name="camed:annotation">
<xsl:attribute name="item">
<xsl:choose> <xsl:when test="count(./@name) > 0">/<xsl:value-of select="$this-parent"/>/@asm1:<xsl:value-of select="./@name"/></xsl:when> <xsl:when test="count(./@ref) > 0">/<xsl:value-of select="$this-parent"/>/@<xsl:value-of select="./@ref"/></xsl:when> <xsl:otherwise/> </xsl:choose>
</xsl:attribute> <camed:documentation type="Definition"><xsl:value-of select="./xsd:annotation/xsd:documentation"/></camed:documentation>
</xsl:element>
</xsl:if>
</xsl:if>
<!-- xsl:if test="count($this/attribute::*) > 0">
<xsl:call-template name="putAttribs">
<xsl:with-param name="attribs" select="$this/attribute::*"/>
</xsl:call-template>
</xsl:if --> <!-- xsl:if test="count($this/descendant::*) = 0">
<xsl:value-of select="$this/node()"/>
</xsl:if --> <xsl:if test="count($this/descendant::*) > 0">
<xsl:variable name="parent-tag">
<xsl:choose>
<xsl:when test="local-name($this/.) = 'complexType' and(count(./@name) > 0)">/asm1:<xsl:value-of select="./@name"/></xsl:when> <xsl:when test="local-name($this/.) = 'sequence'">/asm1:<xsl:value-of select=".//xsd:element/@name"/></xsl:when> <xsl:otherwise><xsl:value-of select="$this-parent"/></xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:for-each select="$this/child::*">
<xsl:call-template name="doIt">
<xsl:with-param name="this" select="."/> <xsl:with-param name="this-parent" select="$parent-tag"/> <xsl:with-param name="last-parent">
<xsl:choose>
<xsl:when test="$this-parent = $parent-tag"><xsl:value-of select="$last-parent"/></xsl:when> <xsl:otherwise><xsl:value-of select="$this-parent"/></xsl:otherwise>
</xsl:choose>
</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</xsl:if>
</xsl:template> <xsl:template name="putAttribs">
<xsl:param name="attribs"/> <xsl:for-each select="$attribs">
<xsl:attribute name="{local-name()}"><xsl:value-of select="."/></xsl:attribute>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
CAM Wiki