source: SMC/trunk/SMC/src/xsl/terms2graph.xsl @ 3462

Last change on this file since 3462 was 3462, checked in by vronk, 11 years ago

added documentation, reworked terms-lookup, typing of nodes

File size: 28.7 KB
Line 
1<?xml version="1.0" encoding="UTF-8"?>
2<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:my="myFunctions" version="2.0" xml:space="default">
3    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" scope="stylesheet">
4        <xd:desc>
5            <xd:p>generate a graph (xml) of CMD-component reuse (based on smc:cmd-terms)</xd:p>
6            <xd:p>also takes instance-data summary as input - tries to merge with cmd-terms data (to get the ids)</xd:p>
7   
8            <xd:p>an integrated version, that based on format-param directly produced json, had very bad performance,
9                so the functionality is split. first step is here, generating the graph-xml,
10                which is then used as input for graph2json-d3.xsl, or graph2dot.xsl</xd:p>
11           
12            <xd:p><xd:b>Created on:</xd:b> 2012-05-17 (based on CMDI/scripts/cmd2dot.xsl)</xd:p>
13            <xd:p><xd:b>Modified:</xd:b> 2012-12-05, 2013-06, 2013-08-21</xd:p>
14            <xd:p><xd:b>Author:</xd:b> m</xd:p>
15           
16        </xd:desc>
17    </xd:doc>
18
19    <xsl:output method="xml" encoding="utf-8"/>
20
21    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
22        <xd:desc>
23            <xd:p></xd:p>
24        </xd:desc>
25    </xd:doc>
26    <xsl:param name="profiles" select="''"/>  <!--teiHeader-->
27    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
28        <xd:desc>
29            <xd:p></xd:p>
30        </xd:desc>
31    </xd:doc>
32    <xsl:param name="format" select="'xml'"/>  <!-- xml | json-d3 ;  todo: dot, json-jit?  -->
33    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
34        <xd:desc>
35            <xd:p>used as base, when resolving the auxiliary files, that get loaded with doc</xd:p>
36        </xd:desc>
37    </xd:doc>
38    <xsl:param name="base-uri" select="base-uri(/)"/>
39    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
40        <xd:desc>
41            <xd:p>auxiliary data: data categories in the terms format, loaded from dcr-terms.xml</xd:p>
42        </xd:desc>
43    </xd:doc>
44    <xsl:variable name="dcr-terms" select="doc(resolve-uri('dcr-terms.xml',$base-uri))"/>
45
46    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
47        <xd:desc>
48             <xd:p>generate a deep copy of the cmd-terms data - this is necessary due to a problem with Saxon 9.2.1.5 (used by exist; 9.3.0.5 seemed to work) - see enrich-mode templates </xd:p>
49        </xd:desc>
50    </xd:doc>
51    <xsl:variable name="dcr-terms-copy">
52        <xsl:apply-templates select="$dcr-terms" mode="copy"/>
53    </xsl:variable>
54
55    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
56        <xd:desc>
57            <xd:p></xd:p>
58        </xd:desc>
59    </xd:doc>
60    <xsl:param name="rr-relations" select="doc(resolve-uri('rr-relations.xml',$base-uri))"/>
61   
62    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
63        <xd:desc>
64            <xd:p></xd:p>
65        </xd:desc>
66    </xd:doc>
67    <xsl:param name="cmd-terms-uri" select="resolve-uri('cmd-terms-nested.xml',$base-uri)"/>
68    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
69        <xd:desc>
70            <xd:p></xd:p>
71        </xd:desc>
72    </xd:doc>
73    <xsl:param name="cmd-terms" select="doc($cmd-terms-uri)"/>
74    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
75        <xd:desc>
76            <xd:p>generate a deep copy of the cmd-terms data - this is necessary due to a problem with Saxon 9.2.1.5 (used by exist; 9.3.0.5 seemed to work) - see enrich-mode templates </xd:p>
77        </xd:desc>
78    </xd:doc>
79    <xsl:variable name="cmd-terms-copy">
80        <xsl:apply-templates select="$cmd-terms/*" mode="copy"/>
81    </xsl:variable>
82   
83    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
84        <xd:desc>
85            <xd:p>lookup term by path in cmd-terms, when enriching instance data with cmd-terms</xd:p>
86            <xd:pre><Term type="CMD_Component" name="GeneralInfo" datcat="" id="clarin.eu:cr1:c_1359626292113" elem="GeneralInfo" parent="AnnotatedCorpusProfile" path="AnnotatedCorpusProfile.GeneralInfo">
87                    <Term type="CMD_Element" name="ResourceName" datcat="http://www.isocat.org/datcat/DC-2544" id="clarin.eu:cr1:c_1359626292113#ResourceName" elem="ResourceName" parent="GeneralInfo" path="AnnotatedCorpusProfile.GeneralInfo.ResourceName"/>
88                </Term>
89            </xd:pre>
90           
91        </xd:desc>
92    </xd:doc>
93    <xsl:key name="cmd-terms-path" match="Term" use="@path"/>
94
95    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
96        <xd:desc>
97            <xd:p>lookup a profile by name</xd:p>
98            <xd:pre><Termset name="AnnotatedCorpusProfile" id="clarin.eu:cr1:p_1357720977520" type="CMD_Profile" /></xd:pre>
99        </xd:desc>
100    </xd:doc>
101    <xsl:key name="cmd-termset-name" match="Termset" use="@name"/>
102    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
103        <xd:desc>
104            <xd:p>lookup a profile by id</xd:p>
105        </xd:desc>
106    </xd:doc>
107    <xsl:key name="cmd-termset-id" match="Termset" use="@id"/>
108    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
109        <xd:desc>
110            <xd:p>lookup dcr-terms (data categories) by their identifier</xd:p>
111        </xd:desc>
112    </xd:doc>
113    <xsl:key name="dcr-terms" match="Concept" use="@id"/>
114    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
115        <xd:desc>
116            <xd:p>Main template</xd:p>
117            <xd:p>steps performed:</xd:p>
118            <xd:ul>
119                <xd:li>apply optional profile-filter</xd:li>
120                <xd:li>if instance data -> enrich (= merge with cmd-terms)</xd:li> 
121                <xd:li>generate nodes for profiles/components/elements, datcats (if instance data additionally collections) </xd:li>
122                <xd:li>generate edges for profiles -> components -> elements, terms -> datcats, relations (if instance data additionally collections-> profiles) </xd:li>
123                <xd:li>fold nodes and edges ($nodes -> $distinct-nodes, $edges -> $distinct-edges)</xd:li>
124                <xd:li>return full graph-xml</xd:li>
125            </xd:ul>
126        </xd:desc>
127    </xd:doc>
128    <xsl:template match="/">
129<!--        <xsl:value-of select="doc-available(resolve-uri('../data/cmd-terms-nested.xml',$base-uri))"></xsl:value-of>-->
130        <xsl:variable name="filtered-termsets">
131            <xsl:choose>
132                <xsl:when test="not($profiles='')">
133                    <xsl:copy-of select="//Termset[contains($profiles,@id) or contains($profiles,@name)]"/>
134                </xsl:when>
135                <xsl:otherwise>
136                    <xsl:copy-of select="//Termset"/>
137                </xsl:otherwise>
138            </xsl:choose>
139        </xsl:variable>
140       
141        <!-- if instance data - merge with cmd-terms (to get the IDs) -->
142        <xsl:variable name="enriched-termsets">
143            <xsl:choose>
144                <xsl:when test="$filtered-termsets//Termset[@type='CMD_Profile']">
145                    <xsl:copy-of select="$filtered-termsets"/>
146                </xsl:when>
147                <xsl:otherwise>
148                    <xsl:apply-templates select="$filtered-termsets//Termset" mode="enrich"/>
149                </xsl:otherwise>
150            </xsl:choose>
151        </xsl:variable>
152        <xsl:variable name="nodes">
153            <!--<xsl:for-each select="$filtered-termsets//Termset/Term">
154           
155                <xsl:variable name="profile" select="$cmd-terms//Termset[@name=current()/@name]"></xsl:variable>
156<!-\-               DEBUG:-<xsl:value-of select="current()/@name"/><xsl:copy-of select="$profile"></xsl:copy-of>-\->
157        -->
158            <xsl:apply-templates select="$enriched-termsets//Termset[@context]" mode="nodes-collections"/>
159            <xsl:apply-templates select="$enriched-termsets//Termset[@type='CMD_Profile']" mode="nodes"/>
160            <xsl:apply-templates select="$enriched-termsets//Term" mode="nodes">
161<!--                    <xsl:with-param name="cmd-terms" select="$profile"></xsl:with-param>-->
162            </xsl:apply-templates>
163            <xsl:apply-templates select="$enriched-termsets//Term" mode="nodes-datcats"/>
164            <xsl:for-each-group select="$rr-relations//Concept" group-by="@id">
165                <xsl:variable name="datcat-id" select="@id"/>
166                <xsl:variable name="get-mnemonic">
167                    <xsl:for-each select="$dcr-terms-copy">
168                        <xsl:copy-of select="key('dcr-terms', $datcat-id)/Term[@type=('mnemonic','label')][1]"/>
169                        <!--                /Concept/Term[@type='mnemonic']-->
170                    </xsl:for-each>
171                </xsl:variable>
172                <xsl:variable name="datcat-name">
173                    <!--            <xsl:variable name="get-mnemonic" select="$dcr-terms//Concept[@id=current()/@datcat]/Term[@type='mnemonic']"/>-->
174                    <xsl:value-of select="if($get-mnemonic ne '') then $get-mnemonic else tokenize($datcat-id,'/')[last()]"/>
175                </xsl:variable>
176                <node id="{@id}" key="{my:normalize(@id)}" name="{$datcat-name}" type="DatCat">
177                    <xsl:copy-of select="@*[not (name()=('count','type'))]"/>
178                </node>
179            </xsl:for-each-group>
180               
181<!--        </xsl:for-each>-->
182        </xsl:variable>
183        <xsl:variable name="edges">
184            <xsl:apply-templates select="$enriched-termsets//Termset[@context]/Term" mode="edges-collections"/>
185            <xsl:apply-templates select="$enriched-termsets//Term" mode="edges"/>
186            <xsl:apply-templates select="$enriched-termsets//Term" mode="edges-datcats"/>
187<!--            <xsl:apply-templates select="$enriched-termsets//Term" mode="edges-profiles-datcats"/>-->
188<!--            <xsl:apply-templates select="$rr-relations//Relation" mode="edges-rels"/>-->
189        </xsl:variable>
190        <xsl:variable name="distinct-nodes">
191            <xsl:for-each-group select="$nodes/*" group-by="@key">
192                <node position="{position()}" count="{(sum(current-group()/@count[number(.)=number(.)]), count(current-group()))[1]}" avg_level="{avg(current-group()/@level)}" sum_level="{sum(current-group()/@level)}">
193                    <xsl:copy-of select="@*[not (name()='count')]"/>
194                </node>
195            </xsl:for-each-group>
196        </xsl:variable>
197        <xsl:variable name="distinct-edges">
198            <xsl:for-each-group select="$edges/*" group-by="concat(@from, @to)">
199                <xsl:variable name="count" select="count(current-group())"/>
200                <xsl:variable name="ix_from" select="$distinct-nodes/*[@key=current()/@from]/@position - 1 "/>
201                <xsl:variable name="ix_to" select="$distinct-nodes/*[@key=current()/@to]/@position - 1"/>
202                <edge ix_from="{$ix_from}" ix_to="{$ix_to}" from="{@from}" to="{@to}" value="{$count}"/>
203            </xsl:for-each-group>
204        </xsl:variable>
205        <xsl:variable name="graph">
206            <graph>
207                <nodes count="{count($filtered-termsets//Term)}">
208                   
209<!--                                                            <xsl:copy-of select="$dcr-terms-copy"/>-->
210                    <xsl:copy-of select="$distinct-nodes"/>
211                </nodes>
212                <edges>
213                    <xsl:copy-of select="$distinct-edges"/>
214<!--                    <debug><xsl:copy-of select="$edges"/></debug>-->
215                </edges>
216            </graph>
217        </xsl:variable>
218
219        <xsl:copy-of select="$graph"/>
220
221    </xsl:template>
222
223    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
224        <xd:desc>
225            <xd:p>Generate nodes for CMD-Profile in cmd-terms</xd:p>
226            <xd:p>Termset = profiles + root component
227                (data is inconsistent sometimes profile is the root component, sometimes a separate components (e.g. imdi-session)</xd:p>
228        </xd:desc>   
229    </xd:doc>
230    <xsl:template match="Termset" mode="nodes">
231       
232        <xsl:variable name="current_profile_key" select="my:normalize(@id)"/>
233        <node id="{@id}" key="{$current_profile_key}" name="{@name}" type="Profile" level="0" count="{@count}" path="{@path}">
234            <!--       <xsl:value-of select="$equivalent_schema_term"></xsl:value-of>-->
235        </node>
236        <!-- if root component not profile generate a separte node for it -->
237        <xsl:if test="xs:string(@id) ne Term/xs:string(@id)">
238            <xsl:for-each select="Term">
239                <node id="{@id}" key="{my:normalize(@id)}" name="{@name}" type="Component" level="1" count="{@count}" path="{@path}"/>
240            </xsl:for-each>
241        </xsl:if>
242    </xsl:template> 
243       
244    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
245        <xd:desc>
246            <xd:p>Generate nodes for CMD-Components (and CMD-Profiles in instance-data) </xd:p>
247            <xd:p>Expects Terms with @id-attribute, so instance data has to be enriched first</xd:p>
248            <xd:pre><Termset name="Bedevaartbank" id="clarin.eu:cr1:p_1280305685223" type="CMD_Profile">
249        <Term type="CMD_Component" name="Bedevaartbank" datcat="" id="clarin.eu:cr1:p_1280305685223" elem="Bedevaartbank" parent="" path="Bedevaartbank"/>
250        <Term type="CMD_Component" name="Database" datcat="" id="clarin.eu:cr1:c_1280305685207" elem="Database" parent="Bedevaartbank" path="Bedevaartbank.Database"/>
251            </Termset>
252            </xd:pre>
253        </xd:desc>       
254    </xd:doc>
255    <xsl:template match="Term[Term]" mode="nodes">
256   
257        <xsl:variable name="current_comp_key" select="my:normalize(@id)"/>
258        <xsl:variable name="type">
259            <xsl:choose>
260                <xsl:when test="@type='CMD_Profile' or parent::Termset">Profile</xsl:when>
261                <xsl:when test="@type='CMD_Component'">Component</xsl:when>
262                <!-- pass special types -->
263                <xsl:otherwise>
264                    <xsl:value-of select="@type"/>
265                </xsl:otherwise>
266            </xsl:choose>
267        </xsl:variable>
268        <xsl:variable name="level" select="count(ancestor::Term)"/>
269        <node id="{@id}" key="{$current_comp_key}" name="{@name}" type="{$type}" level="{$level}" count="{@count}" path="{@path}">
270            <!--       <xsl:value-of select="$equivalent_schema_term"></xsl:value-of>-->
271        </node>
272    </xsl:template>
273    <!--
274    <!-\- not root components = (mostly) profiles -\->
275    <xsl:template match="Term[not(parent::Termset)][Term]" mode="nodes">
276        <xsl:param name="cmd-terms" select="$cmd-terms"/>   
277        <!-\-<xsl:variable name="current_comp_key" select="my:normalize(concat(@id, '_', @name))" />-\->
278    <!-\-<xsl:variable name="equivalent-cmd-term"
279        select="$cmd-terms//Term[@path=current()/@path]/@id" />
280    -\->
281        <xsl:variable name="current_comp_key" select="my:normalize(@id)"/>
282        <xsl:variable name="type" select="'Component'">
283            <!-\-<xsl:choose>
284                <xsl:when test="@parent=''">Profile</xsl:when>
285                <xsl:otherwise>Component</xsl:otherwise>
286            </xsl:choose>-\->
287        </xsl:variable>
288        <xsl:variable name="level" select="count(ancestor::Term)"/>
289        <node id="{@id}" key="{$current_comp_key}" name="{@name}" type="{$type}" level="{$level}" count="{@count}" path="{@path}">
290<!-\-       <xsl:value-of select="$equivalent_schema_term"></xsl:value-of>-\->
291        </node>
292    </xsl:template>-->
293   
294
295    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
296        <xd:desc>
297            <xd:p>Generate nodes for CMD-Elements (leaf nodes in cmd-terms)</xd:p>
298            <xd:p>Expects Terms with @id-attribute, so instance data has to be enriched first</xd:p>
299            <xd:pre><Term type="CMD_Element" name="applicationType"
300        datcat="http://www.isocat.org/datcat/DC-3786"
301        id="#applicationType"
302        elem="applicationType"
303        parent="AnnotationTool"
304        path="AnnotationTool.applicationType"/>
305    </xd:pre>
306        </xd:desc>       
307    </xd:doc>
308    <xsl:template match="Term[not(Term)]" mode="nodes">       
309        <xsl:variable name="current_elem_key" select="my:normalize(@id)"/>
310        <xsl:variable name="level" select="count(ancestor::Term)"/>
311        <xsl:variable name="type">
312            <xsl:choose>
313                <xsl:when test="@type='CMD_Element'">Element</xsl:when>               
314                <!-- pass special types -->
315                <xsl:otherwise>
316                    <xsl:value-of select="@type"/>
317                </xsl:otherwise>
318            </xsl:choose>
319        </xsl:variable>
320        <node id="{@id}" key="{$current_elem_key}" name="{@name}" type="{$type}" level="{$level}" count="{@count}" path="{@path}"/>
321<!--        <xsl:message><xsl:value-of select="concat(@id, '-', ancestor::Term[1]/@id)"></xsl:value-of></xsl:message>-->
322    </xsl:template>
323   
324    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
325        <xd:desc>
326            <xd:p>process Terms (also Components, not only Elements!) once again, to get datcat-nodes</xd:p>
327        </xd:desc>
328    </xd:doc>
329    <xsl:template match="Term[@datcat][not(@datcat='')]" mode="nodes-datcats">
330        <xsl:variable name="level" select="count(ancestor::Term) + 1"/>
331        <xsl:variable name="datcat-id" select="@datcat"/>
332        <xsl:variable name="get-mnemonic">
333            <xsl:for-each select="$dcr-terms-copy">
334                <xsl:copy-of select="key('dcr-terms', $datcat-id)/Term[@type=('mnemonic','label')][1]"/>
335            </xsl:for-each>
336        </xsl:variable>
337        <xsl:variable name="datcat-name">
338            <xsl:value-of select="if($get-mnemonic ne '') then $get-mnemonic else tokenize(@datcat,'/')[last()]"/>
339        </xsl:variable>
340<!--     DEBUG:get-mnemonic:<xsl:value-of select="$get-mnemonic"/>-->
341        <node id="{$datcat-id}" key="{my:normalize($datcat-id)}" name="{$datcat-name}" type="DatCat" level="{$level}"/>
342    </xsl:template>
343   
344   
345    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
346        <xd:desc>
347            <xd:p>Generate nodes representing collections (in instance-data)</xd:p>
348        </xd:desc>
349    </xd:doc>
350    <xsl:template match="Termset[@context]" mode="nodes-collections">   
351       
352        <xsl:variable name="coll_key" select="my:normalize(@context)"/>
353        <xsl:variable name="type" select="'Collection'"/>
354        <xsl:variable name="level" select="-1"/>
355        <node id="{@context}" key="{$coll_key}" name="{translate(@context, '_', ' ')}" type="{$type}" level="{$level}" count="{sum(Term/@count)}" path="{@context}"/>
356    </xsl:template>
357
358    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
359        <xd:desc>
360            <xd:p>Generate links between the profiles and the collections they appear in</xd:p>
361            <xd:pre>collection -> profile</xd:pre>
362        </xd:desc>
363    </xd:doc>
364    <xsl:template match="Termset[@context]/Term" mode="edges-collections">
365       
366        <!-- cater for both: flat and nested input structure -->
367        <xsl:variable name="parent_coll" select="(parent::Termset/@context)"/>
368        <xsl:variable name="curr_profile_key" select="my:normalize(@id)"/>
369        <edge from="{my:normalize($parent_coll)}" to="{$curr_profile_key}"/>
370    </xsl:template>
371   
372   
373    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
374        <xd:desc>
375            <xd:p>generate bi-directional links for Relations between concepts</xd:p>
376            <xd:p>Sample input data:</xd:p>
377            <xd:pre><Relation type="sameAs">
378        <Concept type="datcat" id="http://www.isocat.org/datcat/DC-2520" role="about"/>
379        <Concept type="datcat" id="http://purl.org/dc/elements/1.1/description"/>
380               
381    </Relation></xd:pre>
382            <xd:pre>concept1 -> concept2, concept2 -> concept1</xd:pre>
383        </xd:desc>
384    </xd:doc>
385    <xsl:template match="Relation" mode="edges-rels">
386        <edge from="{my:normalize(Concept[1]/@id)}" to="{my:normalize(Concept[2]/@id)}" type="{@type}"/>
387        <edge from="{my:normalize(Concept[2]/@id)}" to="{my:normalize(Concept[1]/@id)}" type="-{@type}"/>
388    </xsl:template>
389   
390   
391    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
392        <xd:desc>
393            <xd:p> process both Components and Elements, from the child point of view
394                i.e. find the parent </xd:p>
395        </xd:desc>
396    </xd:doc>
397    <!--    [@type='CMD_Component'] [@parent ne '']-->
398    <xsl:template match="Term[parent::Term]" mode="edges">           
399        <!-- cater for both: flat and nested input structure -->
400<!--        <xsl:variable name="parent" select="(parent::Term[@type='CMD_Component'][1] | preceding-sibling::Term[@type='CMD_Component'][@name=current()/@parent][1])[1]"/>-->
401<!--      not any more: just accept nested structure  -->
402        <xsl:variable name="parent" select="parent::Term[1] "/>
403        <xsl:variable name="current_comp_key" select="my:normalize(@id)"/>
404        <edge from="{my:normalize($parent/@id)}" to="{$current_comp_key}"/>
405    </xsl:template>
406   
407   
408    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
409        <xd:desc>
410            <xd:p>process Terms (not only Elements!) once again, to get links to datcats </xd:p>
411        </xd:desc>
412    </xd:doc>
413    <xsl:template match="Term[exists(@datcat) and not(@datcat='')]" mode="edges-datcats">
414        <xsl:variable name="current_comp_key" select="my:normalize(@id)"/>
415        <edge from="{$current_comp_key}" to="{my:normalize(@datcat)}"/>
416    </xsl:template>
417   
418   
419    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
420        <xd:desc>
421            <xd:p>alternatively process Terms to generate direct links between Profiles and Datcats</xd:p>
422        </xd:desc>
423    </xd:doc>
424    <xsl:template match="Term[exists(@datcat) and not(@datcat='')]" mode="edges-profiles-datcats">
425        <xsl:variable name="current_profile_key" select="my:normalize(ancestor::Termset/@id)"/>
426        <edge from="{$current_profile_key}" to="{my:normalize(@datcat)}"/>
427    </xsl:template>
428    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
429       
430    </xd:doc>
431    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
432        <xd:desc>
433            <xd:p>entry template for enrich-mode</xd:p>
434        </xd:desc>
435        <xd:desc>
436            <xd:p>When enriching the instance data Termset-element represents the collection.
437                Profile is the Termset/Term element </xd:p>
438        </xd:desc>
439    </xd:doc>
440    <xsl:template match="Termset" mode="enrich">
441       
442        <!-- get the correct profile matching on the name of the top element
443            is currently not used due to the bug - rather the global variable $cmd-terms-copy is consulted on every lookup -->
444        <xsl:variable name="profile" select="$cmd-terms-copy//Termset[@name=current()/Term/@name]"/>
445<!--                        DEBUG:-<xsl:value-of select="current()/@name"/><xsl:copy-of select="$profile"></xsl:copy-of>-->
446        <xsl:copy>
447            <xsl:copy-of select="@*"/>
448            <xsl:apply-templates select="Term" mode="enrich">
449            <!--    <xsl:with-param name="cmd-terms">
450                    <xsl:apply-templates select="$profile" mode="copy"/>
451                </xsl:with-param>-->
452            </xsl:apply-templates>
453        </xsl:copy>
454    </xsl:template>
455    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
456        <xd:desc>
457            <xd:p>merges the Term elements from instance-data with corresponding cmd-terms</xd:p>
458            <xd:p>There is a bug(?) in Saxon 9.2.1.5 (used in exist): "Exception: attribute node may not be created after children of containing node."
459            when the $cmd-terms nodeset is passed as a variable. The error disappears when the node is deep-copied().
460            However it is prohibitively expensive to do the copy of the context-profile on every term,
461            thus rather the global variable $cmd-terms-copy is used.
462            WATCHME: There may be a problem with correct matching!
463            In Saxon 9.3.0.5 (Oxygen) no such error occurs.</xd:p>
464        </xd:desc>
465        <xd:param name="cmd-terms">obsoleted, because unusable due to the error</xd:param>
466    </xd:doc>
467   
468    <xsl:template match="Term" mode="enrich">
469<!--        <xsl:param name="cmd-terms" select="$cmd-terms"/>-->
470        <xsl:variable name="curr_path" select="xs:string(@path)"/>
471        <xsl:variable name="equivalent-cmd-term">
472            <xsl:call-template name="get-equivalent-cmd-term">
473<!--                <xsl:with-param name="cmd-terms" select="$cmd-terms"/>-->
474<!--                <xsl:with-param name="cmd-terms">                   
475                    <xsl:apply-templates select="$cmd-terms" mode="copy"/>
476                </xsl:with-param>-->               
477                <xsl:with-param name="key" select="xs:string(@path)"/>
478                <xsl:with-param name="isProfile" select="exists(parent::Termset)"/>
479            </xsl:call-template>
480        </xsl:variable>
481<!--        <xsl:message><debug><xsl:copy-of select="$equivalent-cmd-term"/></debug> </xsl:message>-->
482<!--        <xsl:variable name="current_elem_key" select="my:normalize((@id,$equivalent-cmd-term)[1])" />-->
483        <!--            <xsl:attribute name="curr_path" select="$curr_path"/>-->
484        <Term>
485            <xsl:copy-of select="@*"/>
486            <xsl:choose>
487                <xsl:when test="count($equivalent-cmd-term/*) = 1">
488                    <xsl:copy-of select="$equivalent-cmd-term/*/(@type,@parent,@id,@datcat)"/>
489                </xsl:when>
490                <xsl:when test="count($equivalent-cmd-term/*) &gt; 1">
491                    <xsl:attribute name="type" select="concat('ERROR-ambigue-', count($equivalent-cmd-term/*))"/>
492                    <xsl:copy-of select="$equivalent-cmd-term/*[1]/(@parent,@id,@datcat)"/>
493                </xsl:when>
494                <xsl:otherwise><!-- if no equivalent term find - use path as id and mark as missing -->
495                    <xsl:attribute name="id" select="xs:string(@path)"/>
496                    <xsl:attribute name="type">ERROR-cmd-term-missing</xsl:attribute>
497                </xsl:otherwise>
498            </xsl:choose>
499
500            <!--          type="{$equivalent-cmd-term/*/@type}" id="{$equivalent-cmd-term/*/@id}"  <xsl:copy-of select="$equivalent-cmd-term/*/(@parent,@id)"/><xsl:copy-of select="@*"/>-->
501<!--            <xsl:value-of select="$equivalent-cmd-term" />-->
502            <xsl:apply-templates select="Term" mode="enrich">
503
504            </xsl:apply-templates>
505        </Term>
506    </xsl:template>
507
508    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
509        <xd:desc>
510            <xd:p>helper template handling lookup of corresponding cmd-terms (lookup in post-loaded data)</xd:p>
511        </xd:desc>
512        <xd:param name="cmd-terms">data to look in</xd:param>
513        <xd:param name="key">key to look for</xd:param>
514        <xd:param name="isProfile">indicate, if we are looking for a profile</xd:param>
515    </xd:doc>
516    <xsl:template name="get-equivalent-cmd-term">
517        <xsl:param name="cmd-terms" select="$cmd-terms-copy"/>
518        <xsl:param name="key" select="xs:string(@path)"/>
519        <xsl:param name="isProfile" select="false()"/>
520<!--        <xsl:message><xsl:value-of select="concat($key,'-',$isProfile)"></xsl:value-of></xsl:message>-->
521        <xsl:choose>
522            <xsl:when test="$isProfile">
523                <xsl:for-each select="$cmd-terms">
524                    <xsl:copy-of select="key('cmd-termset-name',$key)"/>
525                </xsl:for-each>
526            </xsl:when>
527            <xsl:otherwise>
528                <xsl:for-each select="$cmd-terms">
529                    <xsl:copy-of select="key('cmd-terms-path',$key)"/>
530                </xsl:for-each>
531            </xsl:otherwise>
532        </xsl:choose>
533    </xsl:template>
534   
535    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
536        <xd:desc>
537            <xd:p>helper-function translating ids and similar to (javascript-)safe keys, removing special characters</xd:p>
538        </xd:desc>
539        <xd:param name="value"></xd:param>
540    </xd:doc>
541    <xsl:function name="my:normalize">
542        <xsl:param name="value"/>
543        <xsl:value-of select="translate($value,'*/-.'',$@={}:[]()#&gt;&lt; ','XZ__')"/>
544    </xsl:function>
545    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
546        <xd:desc>
547            <xd:p></xd:p>
548        </xd:desc>
549        <xd:param name="value"></xd:param>
550    </xd:doc>
551    <xsl:function name="my:simplify">
552        <xsl:param name="value"/>
553        <xsl:value-of select="replace($value,'http://www.clarin.eu/cmd/components/','cmd:')"/>
554    </xsl:function>
555    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
556        <xd:desc>
557            <xd:p></xd:p>
558        </xd:desc>
559    </xd:doc>
560    <xsl:template match="text()"/>
561   
562    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
563        <xd:desc>
564            <xd:p>copy-mode - util-template, generate a deep copy </xd:p>
565        </xd:desc>
566    </xd:doc>
567    <xsl:template match="*|@*" mode="copy">
568        <xsl:copy>
569            <xsl:apply-templates select="*|@*|text()" mode="copy"/>
570        </xsl:copy>
571    </xsl:template>
572   
573    <xd:doc xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl">
574        <xd:desc>
575            <xd:p>copy-mode: copy text</xd:p>
576        </xd:desc>
577    </xd:doc>
578    <xsl:template match="text()" mode="copy">
579        <xsl:copy/>
580    </xsl:template>
581   
582   
583</xsl:stylesheet>
Note: See TracBrowser for help on using the repository browser.