Mercurial > pub > ModelGenerator
annotate xslt/model.xsl @ 12:191b81b2052b
first version of the xslt transform from xml to json
author | cin |
---|---|
date | Mon, 09 Apr 2018 06:43:46 +0300 |
parents | 19a8a71eaa54 |
children |
rev | line source |
---|---|
2 | 1 <?xml version="1.0" encoding="UTF-8"?> |
2 <xsl:stylesheet version="1.0" | |
3 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:m="http://implab.org/schemas/data-model.v1.xsd" | |
4 xmlns:t="http://implab.org/schemas/temp" xmlns:exsl="http://exslt.org/common" | |
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
5 exclude-result-prefixes="m xsl exsl"> |
2 | 6 |
7 <xsl:import href="preprocess.xsl" /> | |
8 <xsl:include href="text-tools.xsl"/> | |
9 | |
10 <xsl:output method="xml" indent="yes" /> | |
11 | |
12 <xsl:key name="type" match="m:package/m:*" use="@name" /> | |
13 | |
14 <xsl:template match="/"> | |
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
15 <xsl:apply-templates select="$module" mode="document" /> |
2 | 16 </xsl:template> |
17 | |
18 <!-- code generation --> | |
19 | |
20 <!-- disable default template --> | |
21 <xsl:template match="*|text()" mode="document" /> | |
22 | |
23 <xsl:template match="t:module" mode="document"> | |
24 <xsl:apply-templates mode="document" /> | |
25 </xsl:template> | |
26 | |
3 | 27 |
2 | 28 |
29 <!-- member resolution traits --> | |
30 | |
31 <!-- Resolves members using given criteria | |
32 @param type | |
33 the name of the type whose members are inspected | |
34 @param memberName | |
35 the name of the member to lookup | |
36 @param scope | |
37 the scope where to look (members, properties, keys, relations) | |
38 | |
39 This template recursively inspects the given type down to it's inheritance | |
40 hierarchy and outputs members matching criteria. | |
41 --> | |
42 <xsl:template name="getMembers"> | |
43 <xsl:param name="type"/> | |
44 <xsl:param name="memberName" select="''"/> | |
45 <xsl:param name="scope" select="'members'"/> | |
46 <!-- prevents cyclic references --> | |
47 <xsl:param name="seen" select="/.."/> | |
48 <xsl:for-each select="$module"> | |
49 <xsl:apply-templates select="key('type', $type)" | |
50 mode="lookup-members"> | |
51 <xsl:with-param name="memberName" select="$memberName"/> | |
52 <xsl:with-param name="scope" select="$scope"/> | |
53 <xsl:with-param name="seen" select="$seen"/> | |
54 </xsl:apply-templates> | |
55 </xsl:for-each> | |
56 </xsl:template> | |
57 | |
58 <xsl:template match="*" mode="lookup-members"/> | |
59 | |
60 <xsl:template match="m:entity" mode="lookup-members"> | |
61 <xsl:param name="memberName" select="''"/> | |
62 <xsl:param name="scope" select="'members'"/> | |
63 <xsl:param name="seen"/> | |
64 | |
65 <xsl:variable name="self" select="."/> | |
66 | |
67 <xsl:if test="not($seen[generate-id() = generate-id($self)])"> | |
68 <xsl:variable name="scopeMembers"> | |
69 <xsl:call-template name="selectScopeMembers"> | |
70 <xsl:with-param name="scope" select="$scope"/> | |
71 </xsl:call-template> | |
72 </xsl:variable> | |
73 | |
6 | 74 <xsl:variable name="members" select="exsl:node-set($scopeMembers)/*[not($memberName) or @name=$memberName]"/> |
2 | 75 |
76 <xsl:choose> | |
77 <xsl:when test="$members"> | |
78 <xsl:copy-of select="$members"/> | |
79 </xsl:when> | |
80 <xsl:when test="m:extends"> | |
81 <xsl:call-template name="getMembers"> | |
82 <xsl:with-param name="type" select="m:extends/@type"/> | |
83 <xsl:with-param name="memberName" select="$memberName"/> | |
84 <xsl:with-param name="scope" select="$scope"/> | |
85 <xsl:with-param name="seen" select="$seen | $self"/> | |
86 </xsl:call-template> | |
87 </xsl:when> | |
88 <xsl:otherwise> | |
89 <xsl:call-template name="warn"> | |
90 <xsl:with-param name="msg"> | |
6 | 91 <t:trace msg="failed to resolve {$memberName}, scope={$scope}"/> |
2 | 92 <t:trace msg="inspected classes"> |
93 <xsl:for-each select="$seen | $self"> | |
94 <t:trace msg="{name()} {@name}"/> | |
95 </xsl:for-each> | |
96 </t:trace> | |
97 </xsl:with-param> | |
98 </xsl:call-template> | |
99 </xsl:otherwise> | |
100 </xsl:choose> | |
101 </xsl:if> | |
102 </xsl:template> | |
103 | |
104 <!-- this template implements scope filtering --> | |
105 <xsl:template name="selectScopeMembers"> | |
106 <xsl:param name="scope" select="'members'"/> | |
107 <xsl:choose> | |
108 <xsl:when test="$scope='members'"> | |
109 <xsl:apply-templates mode="filter-members"/> | |
110 </xsl:when> | |
111 <xsl:when test="$scope='keys'"> | |
6 | 112 <xsl:apply-templates mode="filter-keys"/> |
2 | 113 </xsl:when> |
114 <xsl:when test="$scope='properties'"> | |
115 <xsl:apply-templates mode="fiflter-properties"/> | |
116 </xsl:when> | |
117 <xsl:when test="$scope='relations'"> | |
118 <xsl:apply-templates mode="fiflter-relations"/> | |
119 </xsl:when> | |
120 </xsl:choose> | |
121 </xsl:template> | |
122 | |
123 <!-- filter-members --> | |
124 <xsl:template match="*|text()" mode="filter-members"/> | |
125 <xsl:template match="*[@name]" mode="filter-members"> | |
126 <xsl:copy> | |
127 <xsl:copy-of select="@*" /> | |
128 <xsl:attribute name="declaringType"><xsl:value-of select="../@name" /></xsl:attribute> | |
129 <xsl:copy-of select="*" /> | |
130 </xsl:copy> | |
131 </xsl:template> | |
132 | |
133 <!-- filter-keys --> | |
134 <xsl:template match="*|text()" mode="filter-keys"/> | |
135 <xsl:template match="m:primaryKey" mode="filter-keys"> | |
136 <xsl:apply-templates select="." mode="filter-members"/> | |
137 </xsl:template> | |
138 | |
139 <!-- filter-properties --> | |
140 <xsl:template match="*|text()" mode="filter-properties"/> | |
141 <xsl:template match="m:property" mode="filter-properties"> | |
142 <xsl:apply-templates select="." mode="filter-members"/> | |
143 </xsl:template> | |
144 | |
145 <!-- filter-relations --> | |
146 <xsl:template match="*|text()" mode="filter-relations"/> | |
147 <xsl:template match="m:hasA | m:hasMany" mode="filter-relations"> | |
148 <xsl:apply-templates select="." mode="filter-members"/> | |
149 </xsl:template> | |
150 | |
151 | |
152 | |
153 <!-- Resolves primaryKey information for the given type name. | |
154 @returns m:primaryKey node copy with additional attribute | |
155 @declaringType which points to the type where this primaryKey | |
156 was defined. | |
157 --> | |
158 <xsl:template name="getPrimaryKey"> | |
159 <xsl:param name="type" /> | |
160 <xsl:call-template name="getMembers"> | |
161 <xsl:with-param name="type" select="$type"/> | |
6 | 162 <xsl:with-param name="scope" select="'keys'"/> |
2 | 163 </xsl:call-template> |
164 </xsl:template> | |
165 | |
7 | 166 <!-- expand-member templates are used to process relations |
9 | 167 and keys and provide useful information. This mode is designed |
8 | 168 to recursively traverse members expanding details like special |
169 properties generated by relations. | |
170 | |
171 expand-member-reference is special mode used to traverse inside | |
172 members which are referenced from relations. By default this mode | |
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
173 creates deep copy of all elements. |
8 | 174 |
175 Use this templates to produce intermediate model for further | |
176 processing by specific code-generators. | |
7 | 177 |
178 @special - means that the member is a composite part and isn't | |
179 accessible directly | |
180 --> | |
181 | |
8 | 182 <xsl:template match="*" mode="expand-member"> |
9 | 183 <xsl:copy> |
184 <xsl:copy-of select="@*"/> | |
185 <xsl:apply-templates mode="expand-member"/> | |
186 </xsl:copy> | |
8 | 187 </xsl:template> |
188 | |
189 | |
7 | 190 <!-- short form of primaryKey{@name, @type} --> |
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
191 <xsl:template match="m:primaryKey[not(m:member)]" mode="expand-member"> |
9 | 192 <xsl:variable name="pkName" select="concat(@declaringType, 'Pk')"/> |
193 <xsl:variable name="propName" select="@name" /> | |
194 | |
8 | 195 <xsl:variable name="specialProperty"> |
9 | 196 <m:property name="{$propName}" special="true"> |
197 <xsl:copy-of select="@*[not(self::name)]" /> | |
198 <m:hiddenBy name="{$pkName}" type="{@declaringType}"/> | |
7 | 199 <xsl:copy-of select="*" /> |
200 </m:property> | |
8 | 201 </xsl:variable> |
9 | 202 |
8 | 203 <xsl:apply-templates select="exsl:node-set($specialProperty)" mode="expand-member"/> |
9 | 204 <xsl:copy> |
205 <xsl:attribute name="name"><xsl:value-of select="$pkName"/></xsl:attribute> | |
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
206 <xsl:attribute name="declarigType"><xsl:value-of select="@declaringType"/></xsl:attribute> |
9 | 207 <m:member name="{@name}" type="{@declaringType}"/> |
208 </xsl:copy> | |
7 | 209 </xsl:template> |
210 | |
9 | 211 <!-- long form of primaryKey{ member{@name}+ } --> |
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
212 <!-- will be processed using default template --> |
7 | 213 |
9 | 214 <!-- short form of hasA --> |
215 <xsl:template match="m:hasA" mode="expand-member"> | |
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
216 <xsl:variable name="thisPrefix" select="@name"/> |
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
217 |
9 | 218 <xsl:variable name="foreignPk"> |
219 <xsl:call-template name="getPrimaryKey"> | |
220 <xsl:with-param name="type" select="@type"/> | |
221 </xsl:call-template> | |
8 | 222 </xsl:variable> |
9 | 223 <xsl:variable name="expandedPk"> |
224 <xsl:apply-templates select="exsl:node-set($foreignPk)" mode="expand-member"/> | |
225 </xsl:variable> | |
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
226 <xsl:variable name="pkMembers"> |
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
227 <xsl:apply-templates select="exsl:node-set($expandedPk)/*[not(@special)]" mode="resolve-members"/> |
9 | 228 </xsl:variable> |
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
229 <t:fk> |
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
230 <xsl:for-each select="exsl:node-set($pkMembers)/*"> |
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
231 <t:thisKey name="{$thisPrefix}{@name}" matches="{@name}"> |
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
232 <xsl:copy-of select="."/> |
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
233 </t:thisKey> |
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
234 </xsl:for-each> |
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
235 </t:fk> |
7 | 236 </xsl:template> |
237 | |
9 | 238 <!-- short form of hasA with matched keys specified --> |
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
239 <!-- TODO --> |
9 | 240 <xsl:template match="m:hasA[m:thisKey]"> |
241 <xsl:apply-templates select="m:thisKey" mode="generate-fk-properties"/> | |
242 <xsl:copy> | |
243 <xsl:copy-of select="@*"/> | |
244 <xsl:apply-templates mode="expand-member"/> | |
245 </xsl:copy> | |
7 | 246 </xsl:template> |
247 | |
8 | 248 <xsl:template match="m:hasA/m:thisKey" mode="expand-member"> |
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
249 <m:member name="{@name}" matches="{@matches}" type="{../@declaringType}"/> |
7 | 250 </xsl:template> |
251 | |
9 | 252 <!-- long form of hasA --> |
253 <xsl:template match="m:hasA[m:member]" mode="expand-member"> | |
7 | 254 <xsl:apply-templates mode="expand-member"/> |
255 </xsl:template> | |
256 | |
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
257 <!-- resolve-members --> |
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
258 <!-- processes members and copies members to output --> |
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
259 <!-- TODO: Possible recursion --> |
9 | 260 <xsl:template match="m:member" mode="resolve-members"> |
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
261 <xsl:variable name="name" select="@name"/> |
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
262 <xsl:variable name="declaringType" select="@type" /> |
9 | 263 <xsl:choose> |
264 <xsl:when test="/*[@name=$name and @declaringType=$declaringType]"> | |
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
265 <!-- when reference points to a locally defined member --> |
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
266 <!-- locally defined members are already expanded --> |
9 | 267 <xsl:apply-templates select="/*[@name=$name and @declaringType=$declaringType]" mode="resolve-members"/> |
268 </xsl:when> | |
269 <xsl:otherwise> | |
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
270 <!-- otherwise try to use getMembers, then expand it and resolve members --> |
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
271 <xsl:variable name="members"> |
9 | 272 <xsl:call-template name="getMembers"> |
273 <xsl:with-param name="memberName" select="$name"/> | |
274 <xsl:with-param name="type" select="$declaringType"/> | |
275 </xsl:call-template> | |
276 </xsl:variable> | |
10
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
277 <!-- expand resolved members like 'hasA' and 'thisKey' --> |
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
278 <xsl:variable name="expanded"> |
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
279 <xsl:apply-templates select="exsl:node-set($members)" mode="resolve-members"/> |
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
280 </xsl:variable> |
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
281 <!-- skip @special members when resolving --> |
19a8a71eaa54
added test-model.xsl template for testing purpose of model.xsl
cin
parents:
9
diff
changeset
|
282 <xsl:apply-templates select="exsl:node-set($expanded)/*[not(@special)]" mode="resolve-members"/> |
9 | 283 </xsl:otherwise> |
284 </xsl:choose> | |
285 </xsl:template> | |
286 | |
287 <xsl:template match="m:property" mode="resolve-members"> | |
288 <xsl:copy-of select="."/> | |
289 </xsl:template> | |
290 | |
2 | 291 </xsl:stylesheet> |