XSL Transformation of .owl file

F

Fredrik Henricsson

Hey, I'm building an ontology in Protégé and I want to transform parts of it
(e.g. the instances) to HTML with XSL. When I was transforming another file
with 'simple' XML-tags like <author> before, I got it working, but the
OWL-file is formatted differently and I don't know how to access the
elements. I'll post the .owl file below, but this is basically what I want
to get from the file (the course name):

Advanced Knowledge Technology</CourseName>
....
</Course>

Any kind of help is appreciated.

The OWL-file:

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="MasterAI.xsl"?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:eek:wl="http://www.w3.org/2002/07/owl#"
xmlns="http://www.owl-ontologies.com/unnamed.owl#"
xml:base="http://www.owl-ontologies.com/unnamed.owl">
<owl:Ontology rdf:about=""/>
<owl:Class rdf:ID="Programme">
<rdfs:subClassOf>
<owl:Class rdf:ID="MasterAI"/>
</rdfs:subClassOf>
<owl:disjointWith>
<owl:Class rdf:ID="University"/>
</owl:disjointWith>
<owl:disjointWith>
<owl:Class rdf:ID="Course"/>
</owl:disjointWith>
<owl:equivalentClass>
<owl:Class>
<owl:intersectionOf rdf:parseType="Collection">
<owl:Restriction>
<owl:allValuesFrom>
<owl:Class rdf:about="#Course"/>
</owl:allValuesFrom>
<owl:eek:nProperty>
<owl:ObjectProperty rdf:ID="hasCourse"/>
</owl:eek:nProperty>
</owl:Restriction>
<owl:Restriction>
<owl:eek:nProperty>
<owl:ObjectProperty rdf:about="#hasCourse"/>
</owl:eek:nProperty>
<owl:someValuesFrom>
<owl:Class rdf:about="#Course"/>
</owl:someValuesFrom>
</owl:Restriction>
</owl:intersectionOf>
</owl:Class>
</owl:equivalentClass>
</owl:Class>
<owl:Class rdf:about="#Course">
<owl:disjointWith>
<owl:Class rdf:about="#University"/>
</owl:disjointWith>
<rdfs:subClassOf rdf:resource="#MasterAI"/>
<owl:disjointWith rdf:resource="#Programme"/>
</owl:Class>
<owl:Class rdf:about="#University">
<rdfs:subClassOf rdf:resource="#MasterAI"/>
<owl:disjointWith rdf:resource="#Course"/>
<owl:equivalentClass>
<owl:Class>
<owl:intersectionOf rdf:parseType="Collection">
<owl:Restriction>
<owl:eek:nProperty>
<owl:ObjectProperty rdf:ID="hasProgramme"/>
</owl:eek:nProperty>
<owl:allValuesFrom rdf:resource="#Programme"/>
</owl:Restriction>
<owl:Restriction>
<owl:someValuesFrom rdf:resource="#Programme"/>
<owl:eek:nProperty>
<owl:ObjectProperty rdf:about="#hasProgramme"/>
</owl:eek:nProperty>
</owl:Restriction>
</owl:intersectionOf>
</owl:Class>
</owl:equivalentClass>
<owl:disjointWith rdf:resource="#Programme"/>
</owl:Class>
<owl:Class rdf:ID="ProgrammeAI">
<rdfs:subClassOf rdf:resource="#Programme"/>
</owl:Class>
<owl:ObjectProperty rdf:about="#hasProgramme">
<rdfs:domain rdf:resource="#University"/>
<rdf:type
rdf:resource="http://www.w3.org/2002/07/owl#InverseFunctionalProperty"/>
<rdfs:range rdf:resource="#Programme"/>
<owl:inverseOf>
<owl:FunctionalProperty rdf:ID="isProgrammeOf"/>
</owl:inverseOf>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:about="#hasCourse">
<rdfs:range rdf:resource="#Course"/>
<rdfs:domain rdf:resource="#Programme"/>
<owl:inverseOf>
<owl:ObjectProperty rdf:ID="isCourseOf"/>
</owl:inverseOf>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:about="#isCourseOf">
<rdfs:domain rdf:resource="#Course"/>
<owl:inverseOf rdf:resource="#hasCourse"/>
<rdfs:range rdf:resource="#Programme"/>
</owl:ObjectProperty>
<owl:DatatypeProperty rdf:ID="CourseName">
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
<rdfs:domain rdf:resource="#Course"/>
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#FunctionalProperty"/>
</owl:DatatypeProperty>
<owl:DatatypeProperty rdf:ID="CourseECTS">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#FunctionalProperty"/>
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#float"/>
<rdfs:domain rdf:resource="#Course"/>
</owl:DatatypeProperty>
<owl:FunctionalProperty rdf:ID="ProgrammeName">
<rdfs:domain rdf:resource="#Programme"/>
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#DatatypeProperty"/>
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
</owl:FunctionalProperty>
<owl:FunctionalProperty rdf:ID="UniversityName">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#DatatypeProperty"/>
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
<rdfs:domain rdf:resource="#University"/>
</owl:FunctionalProperty>
<owl:FunctionalProperty rdf:about="#isProgrammeOf">
<owl:inverseOf rdf:resource="#hasProgramme"/>
<rdfs:range rdf:resource="#University"/>
<rdfs:domain rdf:resource="#Programme"/>
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#ObjectProperty"/>
</owl:FunctionalProperty>

Advanced Knowledge Technology</CourseName>
<isCourseOf>
Mens-Machine Communicatie en Artificial Intelligence</ProgrammeName>
<hasCourse rdf:resource="#AdvancedKnowledgeTechnology"/>
<isProgrammeOf>
Groningen(RuG)</UniversityName>
<hasProgramme rdf:resource="#MensMachineCommunicatie"/>
</University>
</isProgrammeOf>
</ProgrammeAI>
5.0</CourseECTS>
</Course>

</rdf:RDF>
 
A

Andy Dingley

Hey, I'm building an ontology in Protégé and I want to transform parts of it
(e.g. the instances) to HTML with XSL.

I can't work out what you're trying to achieve here.

Are you using the ontology, or are you just extracting the instance
data you've stored in it ? Your example appears to be a trivial
example of "Turn some XML into HTML with escaping of the &lt;"
That's in every beginner's XSLT book


Try the following fragments for starters:

<xslt:template mode="copying" match="@*" ><xslt:text>
</xslt:text><xslt:value-of select="name()" />="<xslt:value-of
select="." />"</xslt:template>


<xslt:template mode="copying" match="text()" ><xslt:value-of
select="." /></xslt:template>


<xslt:template mode="copying" match="*" >
&lt;<xslt:value-of select="local-name()" /><xslt:apply-templates
mode="copying" select="@*" /><xslt:choose>

<xslt:when test="*|text()" >&gt;<xslt:apply-templates
select="*|text()" mode="copying" />&lt;/<xslt:value-of
select="local-name()" /></xslt:when>

<xslt:eek:therwise>/</xslt:eek:therwise>
</xslt:choose>&gt;</xslt:template>


<xslt:template name="extract-coursename" >
<xslt:param name="course" select="//ont:Course[1]" />

&lt;<xslt:value-of select="local-name()" /><xslt:apply-templates
mode="copying" select="@*" />&gt;<xslt:for-each select="*" >
<xslt:apply-templates select="." mode="copying" />
</xslt:for-each>&lt;/<xslt:value-of select="local-name()" />&gt;

</xslt:template>




If you're trying to use the ontology itself, then you'll have to give
us an example of what you're looking for as output.

That's not an OWL problem anyway, so much as an RDF / XSLT problem.
RDF is _not_ an appropriate candidate for XSLT ! It's really painful
to do this. You're better with Jena, or an ontology toolkit.

You _can_ do it, providing that the RDF you're working with is a
fairly small subset of the possible valid RDF syntaxes for how it can
be represented in XML. RDF operates at the level of the triples in
its data model, XML barely has a data model and so XSLT/XPath operates
on the raw syntax. If you try and express every valid possibility in
XSLT, you'll go mad.

I'm afraid I don't have time to post a big example, but if you're
looking for an example of how to track RDF through rdf:about, then try
this

Some data:

<rdf:li rdf:about="#material_beads">
<dc:title>Beads</dc:title>
<dc:description>Glass beads</dc:description>
</rdf:li>


<rdf:li rdf:about="#123">
<dc:subject dcq:subjectType="#materials">#material_beads</dc:subject>
<dc:subject dcq:subjectType="#materials">#material_glass</dc:subject>
</rdf:li>


Some XSLT:

<xslt:variable name="item"
select="//rdf:li[(substring-after(@rdf:about,'#')=string ('123'))]" />


<!-- Set of "materisl" referenced -->
<xslt:variable name="materials"
select="//rdf:Description[(substring-after(@rdf:type,'#')='materials')]/rdf:li"
/>

<!-- Set of materials used in this item -->
<xslt:variable name="item-materials"
select="$item/dc:subject[substring-after(@dcq:subjectType,'#')='materials']"
/>


<!--Find description of materials for each material used in item-->
<xslt:for-each select="$item-materials" >
<xslt:variable name="material-description"
select="$materials[@rdf:about = current()]" />

<!-- Do something with it -->
</xslt:for-each>
 
F

Fredrik Henricsson

I can't work out what you're trying to achieve here.
Are you using the ontology, or are you just extracting the instance
data you've stored in it ? Your example appears to be a trivial
example of "Turn some XML into HTML with escaping of the &lt;"
That's in every beginner's XSLT book

Thanks for the extensive response, I've just recently started with XML and
XSLT so it's much appreciated.
I should have been more precise in my question; what I really want to do at
the end is present the instance data
in different ways. To clarify, in my application Universities have
Programmes which in turn have Courses. I want to
show, in HTML, which courses can be found in which universities and in which
programmes, OR show the data from
another perspective, for example which courses are worth 5 ECTS. Since I'm
new to XSLT I do not know which is the best way to approach this, so I tried
traversing the tree like in the following pseudo code:

for each Course
print CourseName
find out which Programme Course belongs to
print ProgrammeName
find out which University Programme belongs to
print UniversityName

The problem I encountered was that when I found the Course, I could not
traverse down to find the ProgrammeName. I don't
have any books on XSLT unfortunately, so my main source is the web. Any tips
on approach or direction would be greatly appreciated.
I've included the .owl file below; the lower part of the file shows the
instance relations and data.

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="MasterAI.xsl"?>

<rdf:RDF
xmlns="file:/C:/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl#"
xmlns:protege="http://protege.stanford.edu/plugins/owl/protege#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:eek:wl="http://www.w3.org/2002/07/owl#"
xmlns:myns="http://www.owl-ontologies.com/unnamed.owl#"
xml:base="file:/C:/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl">
<owl:Ontology
rdf:about="file:/C:/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl"/>
<owl:Ontology rdf:about="http://www.owl-ontologies.com/unnamed.owl"/>
<owl:Class rdf:about="http://www.owl-ontologies.com/unnamed.owl#Programme">
<rdfs:subClassOf>
<owl:Class rdf:about="http://www.owl-ontologies.com/unnamed.owl#MasterAI"/>
</rdfs:subClassOf>
<owl:equivalentClass>
<owl:Class>
<owl:intersectionOf rdf:parseType="Collection">
<owl:Restriction>
<owl:eek:nProperty>
<owl:ObjectProperty
rdf:about="http://www.owl-ontologies.com/unnamed.owl#hasCourse"/>
</owl:eek:nProperty>
<owl:allValuesFrom>
<owl:Class rdf:about="http://www.owl-ontologies.com/unnamed.owl#Course"/>
</owl:allValuesFrom>
</owl:Restriction>
<owl:Restriction>
<owl:someValuesFrom>
<owl:Class rdf:about="http://www.owl-ontologies.com/unnamed.owl#Course"/>
</owl:someValuesFrom>
<owl:eek:nProperty>
<owl:ObjectProperty
rdf:about="http://www.owl-ontologies.com/unnamed.owl#hasCourse"/>
</owl:eek:nProperty>
</owl:Restriction>
</owl:intersectionOf>
</owl:Class>
</owl:equivalentClass>
<owl:disjointWith>
<owl:Class
rdf:about="http://www.owl-ontologies.com/unnamed.owl#University"/>
</owl:disjointWith>
<owl:disjointWith>
<owl:Class rdf:about="http://www.owl-ontologies.com/unnamed.owl#Course"/>
</owl:disjointWith>
</owl:Class>
<owl:Class rdf:about="http://www.owl-ontologies.com/unnamed.owl#Course">
<owl:disjointWith>
<owl:Class
rdf:about="http://www.owl-ontologies.com/unnamed.owl#University"/>
</owl:disjointWith>
<rdfs:subClassOf
rdf:resource="http://www.owl-ontologies.com/unnamed.owl#MasterAI"/>
<owl:disjointWith
rdf:resource="http://www.owl-ontologies.com/unnamed.owl#Programme"/>
</owl:Class>
<owl:Class rdf:about="http://www.owl-ontologies.com/unnamed.owl#University">
<owl:equivalentClass>
<owl:Class>
<owl:intersectionOf rdf:parseType="Collection">
<owl:Restriction>
<owl:allValuesFrom
rdf:resource="http://www.owl-ontologies.com/unnamed.owl#Programme"/>
<owl:eek:nProperty>
<owl:ObjectProperty
rdf:about="http://www.owl-ontologies.com/unnamed.owl#hasProgramme"/>
</owl:eek:nProperty>
</owl:Restriction>
<owl:Restriction>
<owl:someValuesFrom
rdf:resource="http://www.owl-ontologies.com/unnamed.owl#Programme"/>
<owl:eek:nProperty>
<owl:ObjectProperty
rdf:about="http://www.owl-ontologies.com/unnamed.owl#hasProgramme"/>
</owl:eek:nProperty>
</owl:Restriction>
</owl:intersectionOf>
</owl:Class>
</owl:equivalentClass>
<rdfs:subClassOf
rdf:resource="http://www.owl-ontologies.com/unnamed.owl#MasterAI"/>
<owl:disjointWith
rdf:resource="http://www.owl-ontologies.com/unnamed.owl#Course"/>
<owl:disjointWith
rdf:resource="http://www.owl-ontologies.com/unnamed.owl#Programme"/>
</owl:Class>
<owl:Class
rdf:about="http://www.owl-ontologies.com/unnamed.owl#ProgrammeAI">
<rdfs:subClassOf
rdf:resource="http://www.owl-ontologies.com/unnamed.owl#Programme"/>
</owl:Class>
<owl:ObjectProperty
rdf:about="http://www.owl-ontologies.com/unnamed.owl#hasProgramme">
<rdfs:domain
rdf:resource="http://www.owl-ontologies.com/unnamed.owl#University"/>
<rdf:type
rdf:resource="http://www.w3.org/2002/07/owl#InverseFunctionalProperty"/>
<rdfs:range
rdf:resource="http://www.owl-ontologies.com/unnamed.owl#Programme"/>
<owl:inverseOf>
<owl:FunctionalProperty
rdf:about="http://www.owl-ontologies.com/unnamed.owl#isProgrammeOf"/>
</owl:inverseOf>
</owl:ObjectProperty>
<owl:ObjectProperty
rdf:about="http://www.owl-ontologies.com/unnamed.owl#hasCourse">
<rdfs:range
rdf:resource="http://www.owl-ontologies.com/unnamed.owl#Course"/>
<rdfs:domain
rdf:resource="http://www.owl-ontologies.com/unnamed.owl#Programme"/>
<owl:inverseOf>
<owl:ObjectProperty
rdf:about="http://www.owl-ontologies.com/unnamed.owl#isCourseOf"/>
</owl:inverseOf>
</owl:ObjectProperty>
<owl:ObjectProperty
rdf:about="http://www.owl-ontologies.com/unnamed.owl#isCourseOf">
<rdfs:domain
rdf:resource="http://www.owl-ontologies.com/unnamed.owl#Course"/>
<owl:inverseOf
rdf:resource="http://www.owl-ontologies.com/unnamed.owl#hasCourse"/>
<rdfs:range
rdf:resource="http://www.owl-ontologies.com/unnamed.owl#Programme"/>
</owl:ObjectProperty>
<owl:DatatypeProperty
rdf:about="http://www.owl-ontologies.com/unnamed.owl#CourseName">
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
<rdfs:domain
rdf:resource="http://www.owl-ontologies.com/unnamed.owl#Course"/>
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#FunctionalProperty"/>
</owl:DatatypeProperty>
<owl:DatatypeProperty
rdf:about="http://www.owl-ontologies.com/unnamed.owl#CourseECTS">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#FunctionalProperty"/>
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#float"/>
<rdfs:domain
rdf:resource="http://www.owl-ontologies.com/unnamed.owl#Course"/>
</owl:DatatypeProperty>
<owl:FunctionalProperty
rdf:about="http://www.owl-ontologies.com/unnamed.owl#ProgrammeName">
<rdfs:domain
rdf:resource="http://www.owl-ontologies.com/unnamed.owl#Programme"/>
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#DatatypeProperty"/>
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
</owl:FunctionalProperty>
<owl:FunctionalProperty
rdf:about="http://www.owl-ontologies.com/unnamed.owl#UniversityName">
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#DatatypeProperty"/>
<rdfs:range rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
<rdfs:domain
rdf:resource="http://www.owl-ontologies.com/unnamed.owl#University"/>
</owl:FunctionalProperty>
<owl:FunctionalProperty
rdf:about="http://www.owl-ontologies.com/unnamed.owl#isProgrammeOf">
<owl:inverseOf
rdf:resource="http://www.owl-ontologies.com/unnamed.owl#hasProgramme"/>
<rdfs:domain
rdf:resource="http://www.owl-ontologies.com/unnamed.owl#Programme"/>
<rdf:type rdf:resource="http://www.w3.org/2002/07/owl#ObjectProperty"/>
</owl:FunctionalProperty>
<myns:programmeAI rdf:ID="AgentsLanguageSpeech">
<myns:isProgrammeOf>
Utrecht(UU)</myns:UniversityName>
<myns:hasProgramme>
<myns:programmeAI rdf:ID="CognitiveDynamics">
<myns:isProgrammeOf
rdf:resource="file:/C:/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl#UtrechtUU"/>
<myns:programmeName rdf:datatype="http://www.w3.org/2001/XMLSchema#string"
Cognitive Dynamics</myns:programmeName>
<myns:hasCourse>
<myns:Course rdf:ID="DynamicSemantics">
<myns:isCourseOf
rdf:resource="file:/C:/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl#CognitiveDynamics"/>
<myns:CourseName rdf:datatype="http://www.w3.org/2001/XMLSchema#string"
Dynamic Semantics</myns:CourseName>
<myns:isCourseOf>
<myns:programmeAI rdf:ID="FoundationAI">
<myns:isProgrammeOf
rdf:resource="file:/C:/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl#UtrechtUU"/>
<myns:programmeName rdf:datatype="http://www.w3.org/2001/XMLSchema#string"
Foundation of AI</myns:programmeName>
<myns:hasCourse
rdf:resource="file:/C:/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl#DynamicSemantics"/>
</myns:programmeAI>
7.5</myns:CourseECTS>
</myns:Course>
</myns:hasCourse>
</myns:programmeAI>
</myns:hasProgramme>
<myns:hasProgramme
rdf:resource="file:/C:/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl#FoundationAI"/>
<myns:hasProgramme
rdf:resource="file:/C:/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl#AgentsLanguageSpeech"/>
</myns:University>
Agents, Language and Speech Technology</myns:programmeName>
</myns:programmeAI>
<myns:programmeAI rdf:ID="MenMachine">
<myns:hasCourse>
5.0</myns:CourseECTS>
<myns:isCourseOf
rdf:resource="file:/C:/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl#MenMachine"/>
<myns:CourseName rdf:datatype="http://www.w3.org/2001/XMLSchema#string"
Advanced Knowledge Technology</myns:CourseName>
</myns:Course>
Mens-Machine Communicatie en Artificial Intelligence</myns:programmeName>
<myns:isProgrammeOf>
<myns:University rdf:ID="GroningenRUG">
<myns:hasProgramme
rdf:resource="file:/C:/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl#MenMachine"/>
<myns:UniversityName rdf:datatype="http://www.w3.org/2001/XMLSchema#string"
Groningen(RUG)</myns:UniversityName>
</myns:University>
</myns:isProgrammeOf>
</myns:programmeAI>
Artificial Intelligence</myns:programmeName>
<myns:hasCourse>
<myns:Course rdf:ID="LogischeTechniekenindeAI">
<myns:CourseECTS
rdf:datatype="http://www.w3.org/2001/XMLSchema#float">5.0</myns:CourseECTS>
<myns:isCourseOf
rdf:resource="file:/C:/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl#ArtificialIntelligence"/>
<myns:CourseName
rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Logische Technieken
in de AI</myns:CourseName>
</myns:Course>
</myns:hasCourse>
<myns:isProgrammeOf>
<myns:University rdf:ID="AmsterdamVU">
<myns:hasProgramme
rdf:resource="file:/C:/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl#ArtificialIntelligence"/>
<myns:UniversityName
rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Amsterdam(VU)</myns:UniversityName>
</myns:University>
</myns:isProgrammeOf>
</myns:programmeAI>
</rdf:RDF>
 
F

Fredrik Henricsson

Apologies, the most important part of the OWL file was cut off.
<myns:programmeAI rdf:ID="AgentsLanguageSpeech">
<myns:isProgrammeOf>
<myns:University rdf:ID="UtrechtUU">
<myns:UniversityName
rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Utrecht(UU)</myns:UniversityName>
<myns:hasProgramme>
<myns:programmeAI rdf:ID="CognitiveDynamics">
<myns:isProgrammeOf
rdf:resource="file:/C:/Skola/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl#UtrechtUU"/>
<myns:programmeName
rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Cognitive
Dynamics</myns:programmeName>
<myns:hasCourse>
<myns:Course rdf:ID="DynamicSemantics">
<myns:isCourseOf
rdf:resource="file:/C:/Skola/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl#CognitiveDynamics"/>
<myns:CourseName
rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Dynamic
Semantics</myns:CourseName>
<myns:isCourseOf>
<myns:programmeAI
rdf:ID="FoundationAI">
<myns:isProgrammeOf
rdf:resource="file:/C:/Skola/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl#UtrechtUU"/>
<myns:programmeName
rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Foundation of
AI</myns:programmeName>
<myns:hasCourse
rdf:resource="file:/C:/Skola/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl#DynamicSemantics"/>
</myns:programmeAI>
</myns:isCourseOf>
<myns:CourseECTS
rdf:datatype="http://www.w3.org/2001/XMLSchema#float">7.5</myns:CourseECTS>
</myns:Course>
</myns:hasCourse>
</myns:programmeAI>
</myns:hasProgramme>
<myns:hasProgramme
rdf:resource="file:/C:/Skola/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl#FoundationAI"/>
<myns:hasProgramme
rdf:resource="file:/C:/Skola/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl#AgentsLanguageSpeech"/>
</myns:University>
</myns:isProgrammeOf>
<myns:programmeName
rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Agents, Language and
Speech Technology</myns:programmeName>
</myns:programmeAI>
<myns:programmeAI rdf:ID="MenMachine">
<myns:hasCourse>
<myns:Course rdf:ID="AdvancedKnowledgeTechnology">
<myns:CourseECTS
rdf:datatype="http://www.w3.org/2001/XMLSchema#float">5.0</myns:CourseECTS>
<myns:isCourseOf
rdf:resource="file:/C:/Skola/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl#MenMachine"/>
<myns:CourseName
rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Advanced Knowledge
Technology</myns:CourseName>
</myns:Course>
</myns:hasCourse>
<myns:programmeName
rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Mens-Machine
Communicatie en Artificial Intelligence</myns:programmeName>
<myns:isProgrammeOf>
<myns:University rdf:ID="GroningenRUG">
<myns:hasProgramme
rdf:resource="file:/C:/Skola/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl#MenMachine"/>
<myns:UniversityName
rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Groningen(RUG)</myns:UniversityName>
</myns:University>
</myns:isProgrammeOf>
</myns:programmeAI>
<myns:programmeAI rdf:ID="ArtificialIntelligence">
<myns:programmeName
rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Artificial
Intelligence</myns:programmeName>
<myns:hasCourse>
<myns:Course rdf:ID="LogischeTechniekenindeAI">
<myns:CourseECTS
rdf:datatype="http://www.w3.org/2001/XMLSchema#float">5.0</myns:CourseECTS>
<myns:isCourseOf
rdf:resource="file:/C:/Skola/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl#ArtificialIntelligence"/>
<myns:CourseName
rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Logische Technieken
in de AI</myns:CourseName>
</myns:Course>
</myns:hasCourse>
<myns:isProgrammeOf>
<myns:University rdf:ID="AmsterdamVU">
<myns:hasProgramme
rdf:resource="file:/C:/Skola/Utbytesgrejer/Advanced%20Knowledge%20Technology/Exercise%205/MasterAI.owl#ArtificialIntelligence"/>
<myns:UniversityName
rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Amsterdam(VU)</myns:UniversityName>
</myns:University>
</myns:isProgrammeOf>
</myns:programmeAI>
</rdf:RDF>
 
A

Andy Dingley

Thanks for the extensive response, I've just recently started with XML and
XSLT so it's much appreciated.

This is so broken I don't know where to start !

You just can't process an RDF document like this in XSLT.
Teaching students in this way is just wrong, wrong, wrong.
You're using entirely the wrong toolset here, it'll end badly, and you won't learn either technology. You'd be far
better off being taught XSLT with some much simpler XML, then maybe processing this sort of document through Jena.

It is a very bad way to teach you, if you're being taught XSLT and OWL simultaneously. I don't know how much you do
know, but I know of no way in which these could be taught together.

Unless you _understand_ XML (you really grok it), then I can't even begin to explain what OWL is about. If you're trying
to work with OWL, then XSLT is the wrong tool to use. Unless you've got _some_ experience, I can barely even explain
why it's difficult!

So I'll assume you're new to the whole lot you're learning XML / XSLT. This is a good place to be - it's useful stuff.

Don't worry about OWL though. I'm assuming you're being taught this because it's a substitute for DTDs. Now I have big
reservations about this - OWL is quite complicated and it's going to scare the feet off any XML newbie. Particularly
it's based around the RDF data model and you just can't process that (sensibly) with XSLT.

As an XSLT text, then I recommend Michael Kay's book "XSLT"
<http://www.amazon.co.uk/exec/obidos/ASIN/0764543814/codesmiths>

Jeni Tennison's "Beginning XSLT" is also good, and perhaps better as an approachable tutorial
<http://www.amazon.co.uk/exec/obidos/ASIN/1590592603/codesmiths>

Sal Mangano's "XSLT Cookbook" is a valuable text for commercial developers with problems to fix, but it will terrify
learners!


Now I'm still unclear what you're being asked to do here.

We can find the courses trivially

<xslt:template name="extract-courses-details" >
<ul>
<xslt:for-each select="//ont:Course" >
<li>
<xslt:call-template name="extract-course-details" >
<xslt:with-param name="Course" select="." />
</xslt:call-template>
</li>
</xslt:for-each>
</ul>
</xslt:template>


Then for your first example, we can use some simple "XML style" XSLT code to show the course details within this.

<xslt:template name="extract-course-details" >
<xslt:param name="Course" select="/.." />

<!-- print CourseName -->
<p>Course: <xslt:value-of select="$Course/ont:CourseName" /></p>

<!-- print ProgrammeName (the quick hack way) -->
<p>Programme: <xslt:value-of select="$Course/ont:isCourseOf//ont:programmeName" /></p>

</xslt:template>

Now there are a few issues with this.

First of all there are some cardinality issues (how many programmes can a course belong to etc). It's important to
remember these when working with XML / XSLT because most code you write will be working with a node set (potentially
many data items) and your natural assumption is often that you're only looking for one. Then one day your input data
contains more than one, and your application barfs. So either be able to _prove_ that the cardinality is that of a
single value, or else code it to deal correctly with the multiple sets. This is particularly the case for library code.


<xslt:template name="extract-course-details" >
<xslt:param name="Course" select="/.." />

<!-- print CourseName -->
<p>Course: <xslt:value-of select="$Course/ont:CourseName" /></p>

<!-- find out which Programme Course belongs to (not quite so hacky) -->
<xslt:variable name="Programme" select="$Course/ont:isCourseOf/*[1]" />

<!-- print ProgrammeName -->
<p>Programme: <xslt:value-of select="$Programme/ont:programmeName" /></p>

<!-- find out which University Programme belongs to -->
<!-- print UniversityName -->
<p>University: <xslt:value-of select="$Programme/ont:isProgrammeOf/ont:University/ont:UniversityName" /></p>
</xslt:template>

So in the example above, I've coded it to _ONLY_ accept the first one (discarding others). Not only would we have to
deal with the multiples through some form of loop, but we'd have to make sure that the Programme and University
selections stayed in synchronisation (hence the use of the variable) - so if you can do, do it the simple way, but make
sure that it's demonstrably valid to do so in the future as well.


Now notice the use of "//" within the XPath expressions. This is a dangerous technique ! (it's less hazardous to use it
at the start of an expression). It's rarely necessary to use it in an XML context - it's needed here because of the
subclassing of <Programme> as <ProgrammeAI> There's no way to implement this in XSLT, so we have to use this
"wildcard" approach. My skin crawls to do this - it's a huge source of future errors.

It's likely to be reliable to do this here, because <ProgrammeName> is likely (a risky assumption!) to only ever apply
to <Programme> A more sophisticated ontology (arguably better) might have a <name> property for each of these
elements. Then my crude assumption would start to fail - it would depend on the scope of what <isCourseOf> can apply to.

Incidentally, a couple of convention notes:

- <programmeName> would be conventional, because properties begin with a lowercase as a human readability issue.

- You don't need the data typing sprinkled all over the instance data.

- Watch your indentation - it can make code readability much easier.



So how do we solve the "big problem", that of how to process this whole model, cardinality and RDF issues too ?
Well try this example template. I've commented what I could, so this is hopefully an example of "complex RDF-processing
XML for people who already know some XML" that's useful to you.

I'm sorry this example is so clunky - this sort of processing just doesn't fit XSLT's model.

In contrast, the ECTS example would be pretty easy, because that's expressable in "simple XML"
<xsl:for-each select="//myns:Course[myns:CourseECTS &gt; 5.0]" >

Of course, some use of rdf:about or simply changing the serialiser to some other valid XML serialisations would break
things again - you ought to be using a real RDF tool here (like Jena), not an XML tool.

_Please_ post follow up comments to this. I'd like to know just what you're after and whether this is useful to you.





<!--
These have global scope, so we place them outside the templates

Note that we have to account for the subclassing here, but after this we can ignore it.
-->
<xsl:variable name="All-Programmes" select="//myns:programme | //myns:programmeAI" />
<xsl:variable name="All-Universities" select="//myns:University" />



<xsl:template name="extract-course-details-for-RDF-model" >

<xsl:param name="Course" select="/.." />


Course: <xsl:value-of select="$Course/myns:CourseName" />


<!-- The RDF-capable version -->
<!--
Find the set of Programmes for this Course

These are any elements which are either children of isCourseOf or parents of hasCourse
We can't test the element name itself, because of subclassing changing the element name

We either find the Programme elements directly
or we retrieve them via rdf:resource as an attribute of the hasCourse element
-->
<xsl:variable name="Programmes-for-Course" select="
$Course/myns:isCourseOf/*
| $All-Programmes [concat('#', @rdf:ID) = $Course/myns:isCourseOf/@rdf:resource]
| $Course/parent::myns:hasCourse/parent::*
| $All-Programmes [concat('#', @rdf:ID) = $Course/parent::myns:hasCourse/@rdf:resource]
" />

<ul>
<xsl:for-each select="$Programmes-for-Course" >

<!-- This is optional, but we often need to do it whenever we've nested two loops
(as "." scopes to the inner loop)
It also makes the code clearer to read -->
<xsl:variable name="Programme" select="." />

<li>
Programme: <xsl:value-of select="$Programme/myns:programmeName" />


<!-- find out which University(s) this Programme belongs to -->
<xsl:variable name="Universities-for-Programme" select="
$Programme/myns:isProgrammeOf/*
| $All-Universities[concat('#', @rdf:ID) = $Programme/myns:isProgrammeOf/@rdf:resource]
| $Programme/parent::myns:hasProgramme/parent::*
| $All-Universities[concat('#', @rdf:ID) = $Programme/parent::myns:hasProgramme/@rdf:resource]
" />

<!-- Just a frippery to make the display neater -->
<xsl:choose>
<xsl:when test="count($Universities-for-Programme) &gt; 1" >
<ul>
<xsl:for-each select="$Universities-for-Programme" >
<li>University: <xsl:value-of select="./myns:UniversityName" /></li>
</xsl:for-each>
</ul>
</xsl:when>

<xsl:when test="count($Universities-for-Programme) = 1" >
<br />University: <xsl:value-of select="$Universities-for-Programme/myns:UniversityName" />
</xsl:when>
</xsl:choose>


</li>
</xsl:for-each>
</ul>
</xsl:template>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,989
Messages
2,570,207
Members
46,782
Latest member
ThomasGex

Latest Threads

Top