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

Last change on this file since 810 was 810, checked in by dietuyt, 14 years ago

Corrected ISOcat namespace URI

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