source: metadata/trunk/toolkit/comp2schema.xsl @ 81

Last change on this file since 81 was 81, checked in by dietuyt, 15 years ago

Fix date tag in header

  • Property svn:executable set to *
  • Property svn:keywords set to Date
File size: 11.9 KB
Line 
1<?xml version="1.0" encoding="UTF-8"?>
2
3<!--
4    $Rev: 74 $
5    $Date: 2009-11-24 14:52:24 +0000 (Tue, 24 Nov 2009) $
6-->
7
8<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
9    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dcr="http://www.isocat.org">
10    <xsl:strip-space elements="*"/>
11    <xsl:include href="comp2schema-header.xsl"/>
12    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
13
14    <!-- Start includes -->
15   
16    <!-- resolve includes -->
17    <xsl:template match="@*|node()" mode="include">
18        <xsl:copy>
19            <xsl:apply-templates select="@*|node()" mode="include"/>
20        </xsl:copy>
21    </xsl:template>
22
23    <xsl:template match="CMD_Component[@filename]" mode="include">
24        <!-- some of the outer CMD_Component attributes can overwrite the inner CMD_Component attributes -->
25        <xsl:variable name="outer-attr" select="@CardinalityMin|@CardinalityMax"/>
26        <xsl:for-each select="document(@filename)/CMD_ComponentSpec/CMD_Component">
27            <xsl:variable name="inner-attr" select="@*"/>
28            <xsl:copy>
29                <xsl:apply-templates select="$outer-attr" mode="include"/>
30                <xsl:apply-templates select="$inner-attr[not(node-name(.) = $outer-attr/node-name(.))]" mode="include"/>
31                <xsl:apply-templates select="node()" mode="include"/>
32            </xsl:copy>
33        </xsl:for-each>
34    </xsl:template>
35   
36    <!-- Stop includes -->
37   
38    <!-- main -->
39    <xsl:template match="/">
40        <!-- Resolve all includes -->
41        <xsl:variable name="tree">
42            <xsl:apply-templates mode="include"/>
43        </xsl:variable>
44        <!-- Process the complete tree -->
45        <xsl:apply-templates select="$tree/*"/>
46    </xsl:template>
47
48    <!-- generate XSD -->
49    <xsl:template match="/CMD_ComponentSpec">
50
51        <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:dcr="http://www.isocat.org">
52
53            <!--  first create complex types for valueschemes (not inline) -->
54            <xsl:call-template name="CreateComplexTypes"/>
55
56            <xs:element name="CMD">
57                <xs:complexType>
58                    <xs:sequence>
59
60                        <!-- Produce (fixed) header elements (description and resources)-->
61                        <xsl:call-template name="PrintHeader"/>
62
63                        <!-- Then generate the components -->
64                        <xs:element name="Components">
65
66                            <xs:complexType>
67                                <xs:sequence>
68                                    <!--Start with processing the root component once and then process everything else recursively-->
69                                    <xsl:apply-templates select="/CMD_ComponentSpec/CMD_Component"/>
70                                    <!--<xsl:apply-templates select="CMD_ComponentList"/>-->
71                                </xs:sequence>
72                            </xs:complexType>
73                        </xs:element>
74
75                        <!-- Generate the footer -->
76                    </xs:sequence>
77                </xs:complexType>
78            </xs:element>
79        </xs:schema>
80
81    </xsl:template>
82
83
84    <xsl:template name="CreateComplexTypes">
85        <xsl:apply-templates select="CMD_Component" mode="types"/>
86    </xsl:template>
87
88
89    <!-- Start types -->
90
91    <!-- workaround to prevent junk in complex type definitions -->
92    <!--<xsl:template match="AttributeList" mode="preProcess"/>-->
93   
94    <!-- skip all text nodes -->
95    <xsl:template match="text()" mode="types"/>
96
97    <!-- first pass: create the complex types on top of the resulting XSD -->
98    <xsl:template match="ValueScheme" mode="types">
99        <!-- create a unique suffix (the path to the element) to ensure the unicity of the types to be created -->
100       
101       
102       
103        <!-- ignore when this ValueScheme is descendant of an Attribute as we do not allow  CV-attributes in a CV-list -->
104        <xsl:if test="not(../../Attribute)">
105       
106            <xsl:variable name="uniquePath">
107                <xsl:call-template name="printUniquePath"/>
108            </xsl:variable>
109       
110       
111       
112        <!-- first auto-generate a name for the simpletype to be extended -->
113        <xs:simpleType name="simpletype{$uniquePath}">
114            <xs:restriction base="xs:string">
115                <xsl:apply-templates select="pattern"/>
116                <xsl:apply-templates select="enumeration"/>
117            </xs:restriction>
118        </xs:simpleType>
119
120        <!--  then auto-derive a complextype for the attributes -->
121        <xs:complexType name="complextype{$uniquePath}">
122            <xs:simpleContent>
123                <xs:extension base="simpletype{$uniquePath}">
124                    <!-- now look at the attribute list of the CMD_Element parent of this ValueScheme-->
125                    <xsl:apply-templates select="parent::node()/AttributeList/Attribute"/>
126                    <!--<xs:attribute name="attributeName" type="xs:anyURI"/>-->
127                </xs:extension>
128            </xs:simpleContent>
129        </xs:complexType>
130
131   
132        </xsl:if>
133   
134    </xsl:template>
135
136
137
138    <!-- Stop types -->
139
140    <!-- create a unique identifier (the path of the name of the ancestor elements) from the current ValueScheme element -->
141    <xsl:template name="printUniquePath">
142        <xsl:for-each select="ancestor::*">
143            <xsl:if test="string(./@name)">
144                <xsl:text>-</xsl:text>
145                <xsl:value-of select="./attribute::name"/>
146            </xsl:if>
147        </xsl:for-each>
148    </xsl:template>
149
150    <!-- convert all components -->
151    <xsl:template match="CMD_Component">
152        <!--  use override values if specified in parent <CMD_Component filename=...> , otherwise use default cardinality for this component -->
153        <xsl:param name="MinOccurs" select="@CardinalityMin"/>
154        <xsl:param name="MaxOccurs" select="@CardinalityMax"/>
155
156        <xs:element name="{@name}">
157            <xsl:if test="$MinOccurs">
158                <xsl:attribute name="minOccurs">
159                    <xsl:value-of select="$MinOccurs"/>
160                </xsl:attribute>
161            </xsl:if>
162            <xsl:if test="$MaxOccurs">
163                <xsl:attribute name="maxOccurs">
164                    <xsl:value-of select="$MaxOccurs"/>
165                </xsl:attribute>
166            </xsl:if>
167            <!-- Add a dcr:datcat if a ConceptLink attribute is found -->
168            <xsl:apply-templates select="./@ConceptLink"/>
169            <xs:complexType>
170                <xs:sequence>
171                    <!-- process all elements at this level -->
172                    <xsl:apply-templates select="./CMD_Element"/>
173                    <!-- process all components at one level deeper (recursive call) -->
174                    <xsl:apply-templates select="./CMD_Component"/>
175                </xs:sequence>
176                <xs:attribute name="ref" type="xs:IDREF"/>
177                <xsl:apply-templates select="./AttributeList/Attribute"/>
178                <xsl:if test="@ComponentId">
179                    <xs:attribute name="ComponentId" type="xs:anyURI" fixed="{@ComponentId}"/>
180                </xsl:if>
181            </xs:complexType>
182        </xs:element>
183
184    </xsl:template>
185
186    <!-- Process all CMD_Elements, its attributes and children -->
187    <xsl:template match="CMD_Element">
188        <xsl:choose>
189
190            <!-- Highest complexity: both attributes and a valuescheme, link to the type we created during the preprocessing of the ValueScheme -->
191            <xsl:when test="./AttributeList and ./ValueScheme">
192                <xs:element name="{@name}">
193                    <xsl:apply-templates select="./ValueScheme"/>
194                </xs:element>
195            </xsl:when>
196
197            <!-- Medium complexity: attributes but no valuescheme, can be arranged inline -->
198            <xsl:when test="./AttributeList and not(./ValueScheme)">
199                <xs:element name="{@name}">
200                    <xsl:apply-templates select= "@ConceptLink"/>
201                    <xsl:apply-templates select= "@CardinalityMin"/>
202                    <xsl:apply-templates select= "@CardinalityMax"/>
203                    <!-- <xsl:apply-templates select= "and(not(@type) and @*)"/> -->
204                    <xs:complexType>
205                        <xs:simpleContent>
206                            <xs:extension base="{concat('xs:',@ValueScheme)}">
207                                <xsl:apply-templates select="./AttributeList/Attribute"/>
208                            </xs:extension>
209                        </xs:simpleContent>
210                    </xs:complexType>
211                </xs:element>
212            </xsl:when>
213
214            <!-- Simple case: no attributes and no value scheme, 1-to-1 transform to an xs:element, just rename element and attributes -->
215            <xsl:otherwise>
216                <xsl:element name="xs:element">
217                    <xsl:apply-templates select="@* | node()"/>
218                </xsl:element>
219            </xsl:otherwise>
220
221        </xsl:choose>
222
223    </xsl:template>
224
225    <!-- second pass, now link to the earlier created complextype definition -->
226    <xsl:template match="ValueScheme">
227        <xsl:attribute name="type">
228            <xsl:text>complextype</xsl:text>
229            <xsl:call-template name="printUniquePath"/>
230        </xsl:attribute>
231
232    </xsl:template>
233
234    <!-- Convert the AttributeList into real XSD attributes -->
235    <xsl:template match="AttributeList/Attribute">
236        <xs:attribute name="{./Name}">
237           
238            <!-- add some extra stuff if we have a CV attribute -->
239            <xsl:choose>
240               
241                <!-- complex situation: CV or regex -->
242                <xsl:when test="./ValueScheme">
243                    <xs:simpleType>
244                        <xs:restriction base="xs:string">                       
245                            <!-- now use general rules for enumeration or pattern -->
246                            <xsl:apply-templates select="./ValueScheme/*" />
247                        </xs:restriction>
248                    </xs:simpleType>                   
249                </xsl:when>
250               
251                <!-- simple situation: just a basic type -->
252                <xsl:otherwise>
253                    <xsl:attribute name="type"><xsl:value-of select="concat('xs:',./Type)"/></xsl:attribute>
254                </xsl:otherwise>
255           
256            </xsl:choose>
257           
258           
259        </xs:attribute>
260    </xsl:template>
261
262    <!-- Convert patterns -->
263    <xsl:template match="pattern">
264        <xs:pattern value="{self::node()}"/>
265    </xsl:template>
266
267    <!-- Convert enumerations -->
268    <xsl:template match="enumeration">
269
270        <xsl:for-each select="item">
271            <xs:enumeration value="{node()}">
272                <!-- Add a dcr:datcat if a ConceptLink attribute is found -->
273                <xsl:apply-templates select="./@ConceptLink"/>
274                <xsl:apply-templates select="./@AppInfo"/>
275            </xs:enumeration>
276            <!-- dcr:datcat="{@ConceptLink}"/>-->
277        </xsl:for-each>
278    </xsl:template>
279
280    <!--  default action: keep the attributes like they are -->
281    <xsl:template match="@*|node()">
282        <xsl:copy/>
283    </xsl:template>
284
285    <!-- except for those attributes we want to be renamed -->
286    <xsl:template match="@CardinalityMin">
287        <xsl:attribute name="minOccurs">
288            <xsl:value-of select="."/>
289        </xsl:attribute>
290    </xsl:template>
291
292    <xsl:template match="@CardinalityMax">
293        <xsl:attribute name="maxOccurs">
294            <xsl:value-of select="."/>
295        </xsl:attribute>
296    </xsl:template>
297
298    <xsl:template match="@ConceptLink">
299        <xsl:attribute name="dcr:datcat">
300            <xsl:value-of select="."/>
301        </xsl:attribute>
302    </xsl:template>
303
304    <xsl:template match="@AppInfo">
305        <xs:annotation>
306            <xs:appinfo><xsl:value-of select="."/></xs:appinfo>
307        </xs:annotation>
308    </xsl:template>
309
310    <xsl:template match="@ValueScheme">
311        <xsl:attribute name="type">
312            <xsl:value-of select="concat('xs:',.)"/>
313        </xsl:attribute>
314    </xsl:template>
315
316</xsl:stylesheet>
Note: See TracBrowser for help on using the repository browser.