Re: [xsl] RDF/OWL Transformation using XSL - Backtracking Parent Classes ?

Subject: Re: [xsl] RDF/OWL Transformation using XSL - Backtracking Parent Classes ?
From: "James A. Robinson" <jim.robinson@xxxxxxxxxxxx>
Date: Sun, 26 Nov 2006 00:29:25 -0800
> 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[@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.robinson@xxxxxxxxxxxx
Stanford University HighWire Press      http://highwire.stanford.edu/
+1 650 7237294 (Work)                   +1 650 7259335 (Fax)

Current Thread