source: CMDI-Interoperability/CMD2RDF/trunk/xsl/Component2RDF.xsl @ 3799

Last change on this file since 3799 was 3799, checked in by mwindhouwer, 11 years ago

M xsl/CMDRecord2RDF.xsl
M xsl/Component2RDF.xsl

TODO: an Attribute intermediate node to keep has...AttributeValue? and has...AttributeEntity? together

File size: 8.5 KB
Line 
1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE rdf:RDF [
3    <!ENTITY rdf 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
4    <!ENTITY rdfs 'http://www.w3.org/TR/WD-rdf-schema#'>
5    <!ENTITY xsd 'http://www.w3.org/2001/XMLSchema#'>
6    <!ENTITY cmdm 'http://www.clarin.eu/cmd/general.ttl#'>
7]>
8<xsl:stylesheet
9    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
10    xmlns:dcr="http://www.isocat.org/ns/dcr.rdf#"
11    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
12    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
13    xmlns:cmd="http://www.clarin.eu/cmd/"
14    xmlns:cmdm="http://www.clarin.eu/cmd/general.ttl"
15>
16   
17    <xsl:output method="xml" encoding="UTF-8"/>
18   
19    <xsl:param name="base" select="base-uri()"/>
20   
21    <xsl:include href="CMD2RDF.xsl"/>
22   
23    <!-- let's create some RDF -->
24    <xsl:template match="/">
25        <!-- for the output base replace the xml extension by rdf -->
26        <rdf:RDF xml:base="{replace($base,'xml$','')}rdf#">
27            <xsl:apply-templates>
28                <xsl:with-param name="context" tunnel="yes" select="''"/>
29            </xsl:apply-templates>
30        </rdf:RDF>   
31    </xsl:template>
32   
33    <!-- override default text template -->
34    <xsl:template match="text()"/>
35   
36    <!-- some attributes appear everywhere -->
37    <xsl:template name="generic">
38        <xsl:if test="normalize-space(@ConceptLink)!=''">
39            <dcr:datcat>
40                <xsl:value-of select="normalize-space(@ConceptLink)"/>
41            </dcr:datcat>
42        </xsl:if>
43        <xsl:if test="normalize-space(@Documentation)!=''">
44            <rdfs:comment>
45                <xsl:value-of select="normalize-space(@Documentation)"/>
46            </rdfs:comment>
47        </xsl:if>
48    </xsl:template>
49   
50    <!-- a profile (and component?) contains all the nested components as well,
51         but as these are shared we want to also share their RDF representations.
52         So cut off the traversal when there is reuse. -->
53    <xsl:template match="CMD_Component[exists(@ComponentId)]"/>
54
55    <!-- component belonging only to the root profile/component -->
56    <xsl:template match="CMD_Component[empty(@ComponentId)]">
57        <xsl:param name="context" tunnel="yes"/>
58        <!-- extend the context path with this component -->
59        <xsl:variable name="id" select="cmd:path($context,@name)"/>
60        <!-- a component maps to an RDF class -->
61        <rdfs:Class rdf:about="{$id}">
62            <xsl:choose>
63                <xsl:when test="../CMD_ComponentSpec/@isProfile='true'">
64                    <rdfs:subClassOf rdf:resource="&cmdm;Profile"/>
65                </xsl:when>
66                <xsl:otherwise>
67                    <rdfs:subClassOf rdf:resource="&cmdm;Component"/>
68                </xsl:otherwise>
69            </xsl:choose>
70            <xsl:call-template name="generic"/>
71        </rdfs:Class>
72        <!-- continue with the child component/elements -->
73        <xsl:apply-templates>
74            <xsl:with-param name="context" tunnel="yes" select="$id"/>
75        </xsl:apply-templates>
76    </xsl:template>
77   
78    <!-- a CMD element -->
79    <xsl:template match="CMD_Element">
80        <xsl:param name="context" tunnel="yes"/>
81        <!-- extend the context with this element -->
82        <xsl:variable name="id" select="cmd:path($context,@name)"/>
83        <xsl:variable name="has" select="cmd:path($context,concat('has',@name))"/>
84        <!-- element becomes a class to be able to group attributes and value together -->
85        <rdfs:Class rdf:about="{$id}">
86            <rdfs:subClassOf rdf:resource="&cmdm;Element"/>
87            <xsl:call-template name="generic"/>
88        </rdfs:Class>
89        <!-- the value property -->
90        <rdf:Property rdf:about="{$has}ElementValue">
91            <rdfs:subPropertyOf rdf:resource="&cmdm;hasElementValue"/>
92            <!-- the domain of the value property is the class corresponding to the CMD element -->
93            <rdfs:domain rdf:resource="{$id}"/>
94            <xsl:choose>
95                <!-- if the value scheme is an enumeration the range consists of the labels of the values -->
96                <xsl:when test="exists(ValueScheme/enumeration)">
97                    <rdfs:range rdf:resource="&xsd;string"/>
98                </xsl:when>
99                <!-- if the value scheme is an XSD datatype the range becomes the equivalent RDF XSD datatype -->
100                <xsl:when test="exists(@ValueScheme)">
101                    <rdfs:range rdf:resource="&xsd;{cmd:datatype(@ValueScheme)}"/>
102                </xsl:when>
103                <!-- if the value scheme is different, e.g., a regular expression, fall back to xsd:string -->
104                <xsl:otherwise>
105                    <rdfs:range rdf:resource="&xsd;string"/>
106                </xsl:otherwise>
107            </xsl:choose>
108        </rdf:Property>
109        <!-- if there is an value enumeration also have a hasElementEntity property -->
110        <if test="exists(ValueScheme/enumeration)">
111            <rdf:Property rdf:about="{$has}ElementEntity">
112                <rdfs:subPropertyOf rdf:resource="&cmdm;hasElementEntity"/>
113                <!-- the domain of the value property is the class corresponding to the CMD element -->
114                <rdfs:domain rdf:resource="{$id}"/>
115                <!-- the range consists of a superclass for the specific value classes -->
116                <rdfs:range rdf:resource="{$id}Value"/>
117            </rdf:Property>
118        </if>
119        <!-- continue with the attributes and values -->
120        <xsl:apply-templates>
121            <xsl:with-param name="context" tunnel="yes" select="$id"/>
122        </xsl:apply-templates>
123    </xsl:template>
124   
125    <!-- a CDM value -->
126    <xsl:template match="item">
127        <xsl:param name="context" tunnel="yes"/>
128        <xsl:variable name="label" select="."/>
129        <!-- id is the label without whitespace
130             CHECK: is that enough? -->
131        <xsl:variable name="id" select="replace($label,'\s','')"/>
132        <!-- a value in a value scheme becomes a subclass of that scheme -->
133        <rdf:Class rdf:about="{$context}Value{$STEP}{$id}">
134            <rdf:subClassOf rdf:resource="{$context}Value"/>
135            <xsl:call-template name="generic"/>
136            <rdfs:label>
137                <xsl:value-of select="$label"/>
138            </rdfs:label>
139        </rdf:Class>
140    </xsl:template>
141   
142    <!-- a CMD attribute -->
143    <xsl:template match="Attribute">
144        <xsl:param name="context" tunnel="yes"/>
145        <!-- extend the context with this attribute -->
146        <xsl:variable name="id" select="concat(cmd:path($context,Name),'Attribute')"/>
147        <xsl:variable name="has" select="concat(cmd:path($context,concat('has',Name)),'Attribute')"/>
148        <!-- an attribute becomes a property -->
149        <rdf:Property rdf:about="{$has}Value">
150            <rdfs:subPropertyOf rdf:resource="&cmdm;hasAttributeValue"/>
151            <xsl:call-template name="generic"/>
152            <!-- the domain is the CMD element RDF class --> 
153            <rdfs:domain rdf:resource="{$context}"/>
154            <xsl:choose>
155                <!-- if the value scheme is an enumeration the range is the labels -->
156                <xsl:when test="exists(ValueScheme/enumeration)">
157                    <rdfs:range rdf:resource="&xsd;string"/>
158                </xsl:when>
159                <!-- if the value scheme is an XSD datatype the range becomes the equivalent RDF XSD datatype -->
160                <xsl:when test="exists(@Type)">
161                    <rdfs:range rdf:resource="&xsd;{cmd:datatype(Type)}"/>
162                </xsl:when>
163                <!-- if the value scheme is different, e.g., a regular expression, fall back to xsd:string -->
164                <xsl:otherwise>
165                    <rdfs:range rdf:resource="&xsd;string"/>
166                </xsl:otherwise>
167            </xsl:choose>
168        </rdf:Property>
169        <!-- if there is an value enumeration also have a hasAttributeEntity property -->
170        <xsl:if test="exists(ValueScheme/enumeration)">
171            <rdf:Property rdf:about="{$has}Entity">
172                <rdfs:subPropertyOf rdf:resource="&cmdm;hasAttributeEntity"/>
173                <!-- the domain is the CMD element RDF class --> 
174                <rdfs:domain rdf:resource="{$context}"/>
175                <!-- the range consists of a superclass for the specific value classes -->
176                <rdfs:range rdf:resource="{$id}Value"/>
177            </rdf:Property>
178        </xsl:if>
179        <!-- continue with the values -->
180        <xsl:apply-templates>
181            <xsl:with-param name="context" tunnel="yes" select="$id"/>
182        </xsl:apply-templates>
183    </xsl:template>
184
185</xsl:stylesheet>
Note: See TracBrowser for help on using the repository browser.