Added adl2canonical
This commit is contained in:
parent
eba7fa3afb
commit
d52a3d5653
|
@ -13,7 +13,7 @@
|
|||
<!-- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
|
||||
|
||||
<!--
|
||||
$Revision: 1.5 $
|
||||
$Revision: 1.6 $
|
||||
-->
|
||||
|
||||
<!-- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: -->
|
||||
|
@ -130,8 +130,8 @@
|
|||
|
||||
name: the name of this application
|
||||
version: the version number of this application
|
||||
assembly: C# implementation detail, should not be here
|
||||
namespace: C# implementation detail, should not be here
|
||||
assembly: C# implementation detail, DEPRECATED: should not be here
|
||||
namespace: C# implementation detail, DEPRECATED: should not be here
|
||||
xmlns: XML namespace, in case required
|
||||
-->
|
||||
<!ELEMENT application ( documentation?, content?, typedef*, group*, entity*)>
|
||||
|
@ -207,12 +207,12 @@
|
|||
natural-key: if present, the name of a property of this entity which forms
|
||||
a natural primary key [NOTE: Only partly implemented. NOTE: much of
|
||||
the present implementation assumes all primary keys will be
|
||||
integers. This needs to be fixed!] TODO: remove; replace with the
|
||||
integers. This needs to be fixed!] DEPRECATED: remove; replace with the
|
||||
'key' element, below.
|
||||
table: the name of the table in which this entity is stored. TODO: more thought
|
||||
-->
|
||||
<!ELEMENT entity ( documentation?, content?,
|
||||
(property | key | one-to-many | many-to-many | many-to-one)*,
|
||||
<!ELEMENT entity ( documentation?, content?, key?,
|
||||
(property | one-to-many | many-to-many | many-to-one)*,
|
||||
permission*, (form | page | list)*)>
|
||||
<!ATTLIST entity
|
||||
name CDATA #REQUIRED
|
||||
|
@ -360,6 +360,7 @@ property[@type='link']. TODO: Not complete, not yet strictly convinced it's the
|
|||
cascade (%CascadeActions;) #IMPLIED
|
||||
column CDATA #IMPLIED
|
||||
unsaved-value CDATA #IMPLIED>
|
||||
|
||||
<!-- It may be worth extracting properties which are not 'simple' into separate elements; this is equivalent to
|
||||
property[@type='entity']. TODO: Not complete, not yet strictly convinced it's the right solution.
|
||||
-->
|
||||
|
|
285
transforms01/adl2canonical.xslt
Executable file
285
transforms01/adl2canonical.xslt
Executable file
|
@ -0,0 +1,285 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!--
|
||||
C1873 SRU Hospitality
|
||||
adl2canonical.xsl
|
||||
|
||||
(c) 2007 Cygnet Solutions Ltd
|
||||
|
||||
Transform ADL into a canonical form, expanding and making explicit
|
||||
things left implicit in the manually maintained form. Specifically,
|
||||
in the canonicalised form
|
||||
|
||||
(i) every entity element has a key subelement. If it did not have one
|
||||
in the supplied ADL, then a formal primary key is auto generated
|
||||
(ii) every form, page or list has properties='listed'; where the supplied
|
||||
ADL had properties='all' or properties='user-distinct' the correct fields
|
||||
are generated.
|
||||
|
||||
$Author: sb $
|
||||
$Revision: 1.1 $
|
||||
$Date: 2008-02-01 12:43:18 $
|
||||
-->
|
||||
|
||||
<xsl:stylesheet version="1.0"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:exsl="http://exslt.org/common"
|
||||
xmlns:adl="http://cygnets.co.uk/schemas/adl-1.2"
|
||||
xmlns:msxsl="urn:schemas-microsoft-com:xslt">
|
||||
|
||||
<xsl:output encoding="UTF-8" method="text"/>
|
||||
|
||||
<!--
|
||||
The convention to use for naming auto-generated abstract primary keys. Known values are
|
||||
Id - the autogenerated primary key, if any, is called just 'Id'
|
||||
Name - the autogenerated primary key has the same name as the entity
|
||||
NameId - the name of the auto generated primary key is the name of the entity followed by 'Id'
|
||||
Name_Id - the name of the auto generated primary key is the name of the entity followed by '_Id'
|
||||
-->
|
||||
<xsl:param name="abstract-key-name-convention" select="Id"/>
|
||||
<xsl:param name="locale" select="en-UK"/>
|
||||
|
||||
<xsl:template match="adl:application">
|
||||
<xsl:message terminate="no">
|
||||
Abstract key naming convention selected is '<xsl:value-of select="$abstract-key-name-convention"/>'
|
||||
Locale selected is '<xsl:value-of select="$locale"/>'
|
||||
</xsl:message>
|
||||
<xsl:copy>
|
||||
<xsl:comment>
|
||||
***************************************************************************
|
||||
*
|
||||
* ©2007 Cygnet Solutions Ltd
|
||||
*
|
||||
* THIS FILE IS AUTOMATICALLY GENERATED AND SHOULD NOT
|
||||
* BE MANUALLY EDITED.
|
||||
*
|
||||
* Generated using adl2canonical.xsl revision <xsl:value-of select="substring('$Revision: 1.1 $', 12)"/>
|
||||
*
|
||||
***************************************************************************
|
||||
</xsl:comment>
|
||||
<xsl:apply-templates select="@* | node()"/>
|
||||
</xsl:copy>
|
||||
</xsl:template>
|
||||
|
||||
<!-- an entity which already has a key tag - just copy it through -->
|
||||
<xsl:template match="adl:entity[key]">
|
||||
<xsl:comment>
|
||||
entity <xsl:value-of select="@name"/> already has a key - not generating one
|
||||
</xsl:comment>
|
||||
<adl:entity>
|
||||
<xsl:apply-templates select="@* | node()"/>
|
||||
</adl:entity>
|
||||
</xsl:template>
|
||||
|
||||
<!-- an entity which has a '@natural-key' attribute.
|
||||
Since we've got the key tag, I think this should be disallowed -->
|
||||
<xsl:template match="adl:entity[@natural-key]">
|
||||
<xsl:message terminate="no">'@natural-key' is deprecated - use the 'key' sub element instead</xsl:message>
|
||||
<adl:entity>
|
||||
<xsl:variable name="nkey" select="@natural-key"/>
|
||||
<xsl:apply-templates select="@*"/>
|
||||
<!-- children copied through in legal order, to ensure the document remains valid -->
|
||||
<xsl:apply-templates select="adl:documentation"/>
|
||||
<xsl:apply-templates select="adl:content"/>
|
||||
<key>
|
||||
<xsl:apply-templates select="adl:property[@name=$nkey]"/>
|
||||
<xsl:apply-templates select="adl:key/adl:property"/>
|
||||
</key>
|
||||
<xsl:apply-templates select="adl:property[not(@name=$nkey)] | adl:one-to-many | adl:many-to-many | adl:many-to-one"/>
|
||||
<xsl:apply-templates select="adl:permission"/>
|
||||
<xsl:apply-templates select="adl:form | adl:page | adl:list"/>
|
||||
</adl:entity>
|
||||
</xsl:template>
|
||||
|
||||
<!-- an entity which has no explicit key: auto-generate one -->
|
||||
<xsl:template match="adl:entity">
|
||||
<xsl:comment>
|
||||
entity <xsl:value-of select="@name"/> has no key - generating one
|
||||
</xsl:comment>
|
||||
<adl:entity>
|
||||
<!-- copy attributes through -->
|
||||
<xsl:apply-templates select="@*"/>
|
||||
<!-- children copied through in legal order, to ensure the document remains valid -->
|
||||
<xsl:apply-templates select="adl:documentation"/>
|
||||
<xsl:apply-templates select="adl:content"/>
|
||||
<adl:key>
|
||||
<!-- autogenerate a key element... -->
|
||||
<!-- select a name... -->
|
||||
<xsl:variable name="key">
|
||||
<xsl:choose>
|
||||
<xsl:when test="$abstract-key-name-convention='Name'">
|
||||
<xsl:value-of select="@name"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="$abstract-key-name-convention = 'NameId'">
|
||||
<xsl:value-of select="concat( @name, 'Id')"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="$abstract-key-name-convention = 'Name_Id'">
|
||||
<xsl:value-of select="concat( @name, '_Id')"/>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="'Id'"/>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:variable>
|
||||
|
||||
<!-- check that it is unique, and abort hard if not... -->
|
||||
<xsl:if test="descendant::adl:property[@name=$key]">
|
||||
<xsl:message terminate="yes">
|
||||
Entity '<xsl:value-of select="@name"/>' has a property '<xsl:value-of select="$key"/>' which conflicts
|
||||
with your chosen key naming convention <xsl:value-of select="$abstract-key-name-convention"/>. Either:
|
||||
(i) Make property '<xsl:value-of select="$key"/>' an explicit key by putting it in the <key> tag;
|
||||
(ii) Name property '<xsl:value-of select="$key"/>' something else; or
|
||||
(iii) Choose a different key naming convention.
|
||||
</xsl:message>
|
||||
</xsl:if>
|
||||
|
||||
<!-- generate one property, the abstract primary key -->
|
||||
<adl:property type="integer" distinct="system">
|
||||
<xsl:attribute name="name">
|
||||
<xsl:value-of select="normalize-space( $key)"/>
|
||||
</xsl:attribute>
|
||||
</adl:property>
|
||||
</adl:key>
|
||||
<xsl:apply-templates select="adl:property | adl:one-to-many | adl:many-to-many | adl:many-to-one"/>
|
||||
<xsl:apply-templates select="adl:permission"/>
|
||||
<xsl:apply-templates select="adl:form | adl:page | adl:list"/>
|
||||
</adl:entity>
|
||||
</xsl:template>
|
||||
|
||||
<!-- If properties='all', unroll them into a properties='listed' form.
|
||||
We need to do this for lists, pages and forms; there's probably some clever
|
||||
way of doing it all in a oner, but I don't know what that is -->
|
||||
<xsl:template match="adl:form[ @properties='all']">
|
||||
<adl:form properties='listed'>
|
||||
<!-- copy the name attribute through -->
|
||||
<xsl:apply-templates select="@name"/>
|
||||
<!-- children copied through in legal order, to ensure the document remains valid -->
|
||||
<xsl:apply-templates select="adl:documentation"/>
|
||||
<!-- unroll the properties -->
|
||||
<xsl:call-template name="unroll-properties"/>
|
||||
<xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field|
|
||||
adl:fieldgroup|adl:auxlist|adl:verb|
|
||||
adl:permission|adl:pragma"/>
|
||||
</adl:form>
|
||||
</xsl:template>
|
||||
|
||||
<!-- If properties='all', unroll them into a properties='listed' form.
|
||||
We need to do this for lists, pages and forms; there's probably some clever
|
||||
way of doing it all in a oner, but I don't know what that is -->
|
||||
<xsl:template match="adl:page[ @properties='all']">
|
||||
<adl:page properties='listed'>
|
||||
<!-- copy the name attribute through -->
|
||||
<xsl:apply-templates select="@name"/>
|
||||
<!-- children copied through in legal order, to ensure the document remains valid -->
|
||||
<xsl:apply-templates select="adl:documentation"/>
|
||||
<!-- unroll the properties -->
|
||||
<xsl:call-template name="unroll-properties"/>
|
||||
<xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field|
|
||||
adl:fieldgroup|adl:auxlist|adl:verb|
|
||||
adl:permission|adl:pragma"/>
|
||||
</adl:page>
|
||||
</xsl:template>
|
||||
|
||||
<!-- If properties='all', unroll them into a properties='listed' form.
|
||||
We need to do this for lists, pages and forms; there's probably some clever
|
||||
way of doing it all in a oner, but I don't know what that is -->
|
||||
<xsl:template match="adl:list[ @properties='all']">
|
||||
<adl:list properties='listed'>
|
||||
<!-- copy the name attribute through -->
|
||||
<xsl:apply-templates select="@name"/>
|
||||
<!-- children copied through in legal order, to ensure the document remains valid -->
|
||||
<xsl:apply-templates select="adl:documentation"/>
|
||||
<!-- unroll the properties -->
|
||||
<xsl:call-template name="unroll-properties"/>
|
||||
<xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field|
|
||||
adl:fieldgroup|adl:auxlist|adl:verb|
|
||||
adl:permission|adl:pragma"/>
|
||||
</adl:list>
|
||||
</xsl:template>
|
||||
|
||||
<!-- In practice it's likely only to be lists which have properties='user-distinct',
|
||||
but the grammar allows this for pages and forms as well so we'll deal with it -->
|
||||
<xsl:template match="adl:form[ @properties='user-distinct']">
|
||||
<adl:form properties='listed'>
|
||||
<!-- copy the name attribute through -->
|
||||
<xsl:apply-templates select="@name"/>
|
||||
<!-- children copied through in legal order, to ensure the document remains valid -->
|
||||
<xsl:apply-templates select="adl:documentation"/>
|
||||
<!-- unroll the properties -->
|
||||
<xsl:call-template name="unroll-user-distinct"/>
|
||||
<xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field|
|
||||
adl:fieldgroup|adl:auxlist|adl:verb|
|
||||
adl:permission|adl:pragma"/>
|
||||
</adl:form>
|
||||
</xsl:template>
|
||||
|
||||
<!-- In practice it's likely only to be lists which have properties='user-distinct',
|
||||
but the grammar allows this for pages and forms as well so we'll deal with it -->
|
||||
<xsl:template match="adl:page[ @properties='user-distinct']">
|
||||
<adl:page properties='listed'>
|
||||
<!-- copy the name attribute through -->
|
||||
<xsl:apply-templates select="@name"/>
|
||||
<!-- children copied through in legal order, to ensure the document remains valid -->
|
||||
<xsl:apply-templates select="adl:documentation"/>
|
||||
<!-- unroll the properties -->
|
||||
<xsl:call-template name="unroll-user-distinct"/>
|
||||
<xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field|
|
||||
adl:fieldgroup|adl:auxlist|adl:verb|
|
||||
adl:permission|adl:pragma"/>
|
||||
</adl:page>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<!-- In practice it's likely only to be lists which have properties='user-distinct',
|
||||
but the grammar allows this for pages and forms as well so we'll deal with it -->
|
||||
<xsl:template match="adl:list[ @properties='user-distinct']">
|
||||
<adl:list properties='listed'>
|
||||
<!-- copy the name attribute through -->
|
||||
<xsl:apply-templates select="@name"/>
|
||||
<!-- children copied through in legal order, to ensure the document remains valid -->
|
||||
<xsl:apply-templates select="adl:documentation"/>
|
||||
<!-- unroll the properties -->
|
||||
<xsl:call-template name="unroll-user-distinct"/>
|
||||
<xsl:apply-templates select="adl:head|adl:top|adl:foot|adl:field|
|
||||
adl:fieldgroup|adl:auxlist|adl:verb|
|
||||
adl:permission|adl:pragma"/>
|
||||
</adl:list>
|
||||
</xsl:template>
|
||||
|
||||
<!-- unroll all the explicit properties in the ancestor entity of
|
||||
the context (assumed to be form, page or list) into a list of fields -->
|
||||
<xsl:template name="unroll-properties">
|
||||
<xsl:for-each select="ancestor::adl:entity/descendant::adl:property |
|
||||
ancestor::adl:entity/descendant::adl:one-to-many |
|
||||
ancestor::adl:entity/descendant::adl:many-to-many |
|
||||
ancestor::adl:entity/descendant::adl:many-to-one">
|
||||
<adl:field>
|
||||
<xsl:attribute name="property">
|
||||
<xsl:value-of select="@name"/>
|
||||
</xsl:attribute>
|
||||
</adl:field>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
|
||||
<!-- unroll all the user-distinct properties in the ancestor entity of
|
||||
the context (assumed to be form, page or list) into a list of fields.
|
||||
NOTE that n-to-n properties cannot currently be user-distinct and are
|
||||
therefore not inspected -->
|
||||
<xsl:template name="unroll-user-distinct">
|
||||
<xsl:for-each select="ancestor::adl:entity/descendant::adl:property[@distinct='user']">
|
||||
<adl:field>
|
||||
<xsl:attribute name="property">
|
||||
<xsl:value-of select="@name"/>
|
||||
</xsl:attribute>
|
||||
</adl:field>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<!-- copy anything that isn't explicitly matched -->
|
||||
<xsl:template match="@* | node()">
|
||||
<xsl:copy>
|
||||
<xsl:apply-templates select="@* | node()"/>
|
||||
</xsl:copy>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
Loading…
Reference in a new issue