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

Last change on this file since 973 was 973, checked in by dietuyt, 13 years ago

Addition of a mimetype attribute to <ResourceType?>

  • Property svn:executable set to *
  • Property svn:keywords set to Revision
File size: 14.0 KB
Line 
1<?xml version="1.0" encoding="UTF-8"?>
2
3<!--
4    $Rev: 973 $
5    $Date: 2010-05-25 17:16:44 +0200 (Tue, 25 May 2010) $
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/ns/dcr" xmlns:ann="http://www.clarin.eu">
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/ns/dcr">
52            <xs:import namespace="http://www.w3.org/XML/1998/namespace"  schemaLocation="http://www.w3.org/2001/xml.xsd"/>
53           
54           
55
56            <!--  first create complex types for valueschemes (not inline) -->
57            <xsl:call-template name="CreateComplexTypes"/>
58           
59            <!-- then create simple type for the ResourceProxy -->
60            <xsl:call-template name="PrintHeaderType"/>
61
62            <xs:element name="CMD">
63                <xs:complexType>
64                    <xs:sequence>
65
66                        <!-- Produce (fixed) header elements (description and resources)-->
67                        <xsl:call-template name="PrintHeader"/>
68
69                        <!-- Then generate the components -->
70                        <xs:element name="Components">
71
72                            <xs:complexType>
73                                <xs:sequence>
74                                    <!--Start with processing the root component once and then process everything else recursively-->
75                                    <xsl:apply-templates select="/CMD_ComponentSpec/CMD_Component"/>
76                                    <!--<xsl:apply-templates select="CMD_ComponentList"/>-->
77                                </xs:sequence>
78                            </xs:complexType>
79                        </xs:element>
80
81                        <!-- Generate the footer -->
82                    </xs:sequence>
83                </xs:complexType>
84            </xs:element>
85        </xs:schema>
86
87    </xsl:template>
88
89
90    <xsl:template name="CreateComplexTypes">
91        <xsl:apply-templates select="CMD_Component" mode="types"/>
92    </xsl:template>
93
94
95    <!-- Start types -->
96
97    <!-- workaround to prevent junk in complex type definitions -->
98    <!--<xsl:template match="AttributeList" mode="preProcess"/>-->
99   
100    <!-- skip all text nodes -->
101    <xsl:template match="text()" mode="types"/>
102
103    <!-- first pass: create the complex types on top of the resulting XSD -->
104    <xsl:template match="ValueScheme" mode="types">
105        <!-- create a unique suffix (the path to the element) to ensure the unicity of the types to be created -->
106       
107       
108       
109        <!-- ignore when this ValueScheme is descendant of an Attribute as we do not allow  CV-attributes in a CV-list -->
110        <xsl:if test="not(../../Attribute)">
111       
112            <xsl:variable name="uniquePath">
113                <xsl:call-template name="printUniquePath"/>
114            </xsl:variable>
115       
116       
117       
118        <!-- first auto-generate a name for the simpletype to be extended -->
119        <xs:simpleType name="simpletype{$uniquePath}">
120            <xs:restriction base="xs:string">
121                <xsl:apply-templates select="pattern"/>
122                <xsl:apply-templates select="enumeration"/>
123            </xs:restriction>
124        </xs:simpleType>
125
126        <!--  then auto-derive a complextype for the attributes -->
127        <xs:complexType name="complextype{$uniquePath}">
128            <xs:simpleContent>
129                <xs:extension base="simpletype{$uniquePath}">
130                    <!-- now look at the attribute list of the CMD_Element parent of this ValueScheme-->
131                    <xsl:apply-templates select="parent::node()/AttributeList/Attribute"/>
132                    <!--<xs:attribute name="attributeName" type="xs:anyURI"/>-->
133                </xs:extension>
134            </xs:simpleContent>
135        </xs:complexType>
136
137   
138        </xsl:if>
139   
140    </xsl:template>
141
142
143
144    <!-- Stop types -->
145
146    <!-- create a unique identifier (the path of the name of the ancestor elements) from the current ValueScheme element -->
147    <xsl:template name="printUniquePath">
148        <xsl:for-each select="ancestor::*">
149            <xsl:if test="string(./@name)">
150                <xsl:text>-</xsl:text>
151                <xsl:value-of select="./attribute::name"/>
152            </xsl:if>
153        </xsl:for-each>
154    </xsl:template>
155
156    <!-- convert all components -->
157    <xsl:template match="CMD_Component">
158        <!--  use override values if specified in parent <CMD_Component filename=...> , otherwise use default cardinality for this component -->
159        <xsl:param name="MinOccurs" select="@CardinalityMin"/>
160        <xsl:param name="MaxOccurs" select="@CardinalityMax"/>
161
162        <xs:element name="{@name}">
163           
164            <xsl:if test="$MinOccurs">
165                <xsl:attribute name="minOccurs">
166                    <xsl:value-of select="$MinOccurs"/>
167                </xsl:attribute>
168            </xsl:if>
169            <xsl:if test="$MaxOccurs">
170                <xsl:attribute name="maxOccurs">
171                    <xsl:value-of select="$MaxOccurs"/>
172                </xsl:attribute>
173            </xsl:if>
174            <!-- Add a dcr:datcat if a ConceptLink attribute is found -->
175            <xsl:apply-templates select="./@ConceptLink"/>
176                                 
177            <xs:complexType>
178                <xs:sequence>
179                    <!-- process all elements at this level -->
180                    <xsl:apply-templates select="./CMD_Element"/>
181                    <!-- process all components at one level deeper (recursive call) -->
182                    <xsl:apply-templates select="./CMD_Component"/>
183                </xs:sequence>
184                <xs:attribute name="ref" type="xs:IDREF"/>
185                <xsl:apply-templates select="./AttributeList/Attribute"/>
186                <xsl:if test="@ComponentId">
187                    <xs:attribute name="ComponentId" type="xs:anyURI" fixed="{@ComponentId}"/>
188                </xsl:if>
189            </xs:complexType>
190           
191       
192        </xs:element>
193
194    </xsl:template>
195
196    <!-- Process all CMD_Elements, its attributes and children -->
197    <xsl:template match="CMD_Element">
198       
199        <xsl:choose>
200
201            <!-- Highest complexity: both attributes and a valuescheme, link to the type we created during the preprocessing of the ValueScheme -->
202            <xsl:when test="./AttributeList and ./ValueScheme">
203                <xs:element name="{@name}">
204                   
205                    <!-- process all Documentation and DisplayPriority attributes -->
206                    <xsl:call-template name="annotations"/>
207                   
208                    <xsl:apply-templates select= "@ConceptLink"/>
209                    <xsl:apply-templates select= "@CardinalityMin"/>
210                    <xsl:apply-templates select= "@CardinalityMax"/>
211                    <xsl:apply-templates select="./ValueScheme"/>
212               
213                </xs:element>
214            </xsl:when>
215
216            <!-- Medium complexity: attributes but no valuescheme, can be arranged inline -->
217            <xsl:when test="./AttributeList and not(./ValueScheme)">
218                <xs:element name="{@name}">
219                   
220                    <xsl:apply-templates select= "@ConceptLink"/>
221                    <xsl:apply-templates select= "@CardinalityMin"/>
222                    <xsl:apply-templates select= "@CardinalityMax"/>
223                   
224                    <!-- process all Documentation and DisplayPriority attributes -->
225                    <xsl:call-template name="annotations"/>
226                   
227                    <!-- <xsl:apply-templates select= "and(not(@type) and @*)"/> -->
228                    <xs:complexType>
229                        <xs:simpleContent>
230                            <xs:extension base="{concat('xs:',@ValueScheme)}">
231                                <xsl:apply-templates select="./AttributeList/Attribute"/>
232                            </xs:extension>
233                        </xs:simpleContent>
234                    </xs:complexType>
235                </xs:element>
236            </xsl:when>
237
238            <!-- Simple case: no attributes and no value scheme, 1-to-1 transform to an xs:element, just rename element and attributes -->
239            <xsl:otherwise>
240                <xsl:element name="xs:element">
241               
242                    <xsl:apply-templates select="@*[name() != 'Documentation' and name() != 'DisplayPriority'] | node()"/>
243                    <!-- process all Documentation and DisplayPriority attributes -->
244                    <xsl:call-template name="annotations"/>
245                   
246                </xsl:element>
247            </xsl:otherwise>
248
249        </xsl:choose>
250
251    </xsl:template>
252
253    <!-- second pass, now link to the earlier created complextype definition -->
254    <xsl:template match="ValueScheme">
255        <xsl:attribute name="type">
256            <xsl:text>complextype</xsl:text>
257            <xsl:call-template name="printUniquePath"/>
258        </xsl:attribute>
259
260    </xsl:template>
261
262    <!-- Convert the AttributeList into real XSD attributes -->
263    <xsl:template match="AttributeList/Attribute">
264        <xs:attribute name="{./Name}">
265           
266            <!-- add some extra stuff if we have a CV attribute -->
267            <xsl:choose>
268               
269                <!-- complex situation: CV or regex -->
270                <xsl:when test="./ValueScheme">
271                    <xs:simpleType>
272                        <xs:restriction base="xs:string">                       
273                            <!-- now use general rules for enumeration or pattern -->
274                            <xsl:apply-templates select="./ValueScheme/*" />
275                        </xs:restriction>
276                    </xs:simpleType>                   
277                </xsl:when>
278               
279                <!-- simple situation: just a basic type -->
280                <xsl:otherwise>
281                    <xsl:attribute name="type"><xsl:value-of select="concat('xs:',./Type)"/></xsl:attribute>
282                </xsl:otherwise>
283           
284            </xsl:choose>
285           
286           
287        </xs:attribute>
288    </xsl:template>
289
290    <!-- Convert patterns -->
291    <xsl:template match="pattern">
292        <xs:pattern value="{self::node()}"/>
293    </xsl:template>
294
295    <!-- Convert enumerations -->
296    <xsl:template match="enumeration">
297
298        <xsl:for-each select="item">
299            <xs:enumeration value="{node()}">
300                <!-- Add a dcr:datcat if a ConceptLink attribute is found -->
301                <xsl:apply-templates select="./@ConceptLink"/>
302                <xsl:apply-templates select="./@AppInfo"/>
303            </xs:enumeration>
304            <!-- dcr:datcat="{@ConceptLink}"/>-->
305        </xsl:for-each>
306    </xsl:template>
307
308     
309    <!--  default action: keep the attributes like they are -->
310    <xsl:template match="@*|node()">
311        <xsl:copy/>
312    </xsl:template>
313
314     
315    <!-- except for those attributes we want to be renamed -->
316    <xsl:template match="@CardinalityMin">
317        <xsl:attribute name="minOccurs">
318            <xsl:value-of select="."/>
319        </xsl:attribute>
320    </xsl:template>
321
322    <xsl:template match="@CardinalityMax">
323        <xsl:attribute name="maxOccurs">
324            <xsl:value-of select="."/>
325        </xsl:attribute>
326    </xsl:template>
327
328    <xsl:template match="@ConceptLink">
329        <xsl:attribute name="dcr:datcat">
330            <xsl:value-of select="."/>
331        </xsl:attribute>
332    </xsl:template>
333
334    <xsl:template match="@AppInfo">
335        <xs:annotation>
336            <xs:appinfo><xsl:value-of select="."/></xs:appinfo>
337        </xs:annotation>
338    </xsl:template>
339   
340   
341    <xsl:template match="@ValueScheme">
342        <xsl:attribute name="type">
343            <xsl:value-of select="concat('xs:',.)"/>
344        </xsl:attribute>
345    </xsl:template>
346
347    <xsl:template match="@Documentation">
348        <xsl:attribute name="ann:documentation"><xsl:value-of select="."/></xsl:attribute>
349        <!--<xs:documentation><xsl:value-of select="."/></xs:documentation>-->
350    </xsl:template>
351   
352    <xsl:template match="@DisplayPriority">
353        <xsl:attribute name="ann:displaypriority"><xsl:value-of select="."/></xsl:attribute>
354        <!--<xs:appinfo><DisplayPriority><xsl:value-of select="."/></DisplayPriority></xs:appinfo>-->
355    </xsl:template>
356
357    <xsl:template name="annotations">
358        <xsl:if test="@Documentation or @DisplayPriority">
359        <!--<xs:annotation>-->
360            <xsl:apply-templates select= "@Documentation"/>
361            <xsl:apply-templates select= "@DisplayPriority"/>
362        <!--</xs:annotation>-->
363        </xsl:if>
364    </xsl:template>
365
366
367</xsl:stylesheet>
Note: See TracBrowser for help on using the repository browser.