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

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

simplified Term to node, corrected type (parts=relations)

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