It is a bit tricky and sometimes makes your code look ugly though.
Does anybody else have a better suggestion?
That's a pretty good technique, I always forget to take advantage
of keys. I think the technique I wrote about, using simple
recursion to walk down (or up) the tree isn't any prettier -- in
fact, the XPath I gave makes it look ugly.
One possible advantage to the recursion technique is that you
can then create a function which returns a sequence of the
ancestors if you really did need to do backtracking.
If I wanted to take a owl:Class for Daughter and return the
hierarchy from the parent on down (how one would deal with
both parents being listed is an interesting question...):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:local="uri.local-functions"
xmlns:rdf=" http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:owl="http://www.w3.org/2002/07/owl#">
<xsl:output indent="yes"/>
<xsl:template match="/">
<!-- build heirarchy for daughter's parent -->
<xsl:apply-templates mode="hierarchy"
select="local:ancestors-of(/rdf:RDF/owl:Class[(_at_)rdf:ID='Daughter'])[2]"/>
</xsl:template>
<!-- build hierarchy of all owl:Class descendents -->
<xsl:template mode="hierarchy" match="owl:Class">
<xsl:variable name="name" select="local:name-of(.)"/>
<xsl:element name="{$name}">
<xsl:apply-templates mode="#current"
select="//owl:Class[
rdfs:subClassOf[
@rdf:resource=current()/@rdf:about
or owl:Class/@rdf:about=current()/@rdf:about]]"/>
</xsl:element>
</xsl:template>
<xsl:function name="local:name-of" as="xs:string">
<xsl:param name="class" as="element(owl:Class)"/>
<xsl:choose>
<xsl:when test="$class/@rdf:ID">
<xsl:value-of select="$class/@rdf:ID"/>
</xsl:when>
<xsl:when test="$class/@rdf:about">
<xsl:value-of select="substring($class/@rdf:about, 2)"/>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">
<xsl:text>Unable to extrapolate an element name from </xsl:text>
<xsl:sequence select="$class"/>
</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
<!-- find the ancestors to an owl:Class (assumes only one ancestor is
possible) -->
<xsl:function name="local:ancestors-of" as="element(owl:Class)+">
<xsl:param name="class" as="element(owl:Class)"/>
<xsl:variable name="parent-id"
select="$class/rdfs:subClassOf/@rdf:resource,
$class/rdfs:subClassOf/owl:Class/@rdf:about"/>
<xsl:variable name="ancestor" select="$class/../owl:Class[$parent-id =
@rdf:about]"/>
<xsl:choose>
<xsl:when test="$ancestor">
<xsl:sequence select="$class, local:ancestors-of($ancestor)"/>
</xsl:when>
<xsl:otherwise>
<xsl:sequence select="$class"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
</xsl:stylesheet>
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
James A. Robinson
jim(_dot_)robinson(_at_)stanford(_dot_)edu
Stanford University HighWire Press http://highwire.stanford.edu/
+1 650 7237294 (Work) +1 650 7259335 (Fax)
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--