<?xml version="1.0"?>
<!-- This RDF parser has originally written by Dan Connolly, and been put onto the W3C Web in 2000.
     I have reused the parser to manage RDF embedded in an SVG file.

     The RDF parser in XSLT is just the basic RDF syntax per 2.2.1. 
       Basic Serialization Syntax of http://www.w3.org/TR/1999/REC-rdf-syntax-19990222
       2000/10/06 04:41:53 Dan Connolly

     Ivan Herman, W3C
     Last update: $Date: 2001/07/09 11:44:49 $
-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xlink="http://www.w3.org/1999/xlink" exclude-result-prefixes="xsl rdf xlink">
  <xsl:output method="html" indent="yes"/>
  <xsl:variable name="rdfNS" select='"http://www.w3.org/1999/02/22-rdf-syntax-ns#"'/>
  <xsl:variable name="axsvgNS" select='"http://www.w3.org/2001/svgRdf/axsvg-schema.rdf#"'/>
  <xsl:variable name="uriReferenceType" select='"http://www.w3.org/1999/XMLSchema#datatype_uriReference"'/>
  <xsl:variable name="stringType" select='"http://www.w3.org/1999/XMLSchema#datatype_string"'/>
  <xsl:include href="Properties.xsl"/>
  <xsl:template match="rdf:RDF">
    <!-- [1] RDF -->
    <!-- This is the preamble, enclosing the output in HTML.
         The title of the full slide, as well as the (possible) description is used
         to start up the file.
    -->
    <html>
      <head>
        <xsl:call-template name="setTitle"/>
      </head>
      <body>
        <xsl:call-template name="preamble"/>
        <xsl:for-each select="text()[string-length(normalize-space())&gt;0]">
          <xsl:call-template name="badStuff">
            <xsl:with-param name="expected" select='"description"'/>
          </xsl:call-template>
        </xsl:for-each>
        <!-- the real meat... -->
        <xsl:call-template name="description_s"/>
      </body>
    </html>
  </xsl:template>
  <xsl:template name="description_s">
    <xsl:param name="parentSubject"/>
    <xsl:param name="parentPredicate"/>
    <!-- do I need a parentID as well? @@-->
    <xsl:for-each select="*">
      <!-- [2] description -->
      <xsl:variable name="node" select="."/>
      <xsl:choose>
        <!-- REVIEW: about vs. rdf:about? reported Wed, 26 Apr 2000 05:12:05 -0500
             http://lists.w3.org/Archives/Public/www-rdf-comments/2000AprJun/0019.html
         -->
        <xsl:when test="(@rdf:ID and @rdf:about) or (namespace-uri() = $rdfNS and @ID and @about)">
          <xsl:call-template name="badElement">
            <xsl:with-param name="problem" select='"ID and about attribute"'/>
          </xsl:call-template>
        </xsl:when>
        <xsl:when test="@rdf:ID">
          <xsl:call-template name="propertyElt_s">
            <xsl:with-param name="node" select="$node"/>
            <xsl:with-param name="subject" select='concat("#", @rdf:ID)'/>
            <xsl:with-param name="parentSubject" select="$parentSubject"/>
            <xsl:with-param name="parentPredicate" select="$parentPredicate"/>
            <xsl:with-param name="parentElement" select=".."/>
          </xsl:call-template>
          <xsl:call-template name="propAttr_s">
            <xsl:with-param name="subject" select='concat("#", @rdf:ID)'/>
          </xsl:call-template>
        </xsl:when>
        <xsl:when test="(namespace-uri() = $rdfNS) and @ID">
          <xsl:call-template name="propertyElt_s">
            <xsl:with-param name="node" select="$node"/>
            <xsl:with-param name="subject" select='concat("#", @ID)'/>
            <xsl:with-param name="parentSubject" select="$parentSubject"/>
            <xsl:with-param name="parentPredicate" select="$parentPredicate"/>
            <xsl:with-param name="parentElement" select=".."/>
          </xsl:call-template>
          <xsl:call-template name="propAttr_s">
            <xsl:with-param name="subject" select='concat("#", @ID)'/>
          </xsl:call-template>
        </xsl:when>
        <xsl:when test="@rdf:about">
          <xsl:call-template name="propertyElt_s">
            <xsl:with-param name="node" select="$node"/>
            <xsl:with-param name="subject" select="@rdf:about"/>
            <xsl:with-param name="parentSubject" select="$parentSubject"/>
            <xsl:with-param name="parentPredicate" select="$parentPredicate"/>
            <xsl:with-param name="parentElement" select=".."/>
          </xsl:call-template>
          <xsl:call-template name="propAttr_s">
            <xsl:with-param name="subject" select="@rdf:about"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:when test="(namespace-uri() = $rdfNS) and @about">
          <xsl:call-template name="propertyElt_s">
            <xsl:with-param name="node" select="$node"/>
            <xsl:with-param name="subject" select="@about"/>
            <xsl:with-param name="parentSubject" select="$parentSubject"/>
            <xsl:with-param name="parentPredicate" select="$parentPredicate"/>
            <xsl:with-param name="parentElement" select=".."/>
          </xsl:call-template>
          <xsl:call-template name="propAttr_s">
            <xsl:with-param name="subject" select="@about"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
          <!-- Anonymous node -->
          <!-- I do not need the description of an anonymous node, ie, I set the name to an empty string! -->
          <!-- <xsl:variable name="genid" select='concat("#,", generate-id())'/> -->
          <xsl:variable name="genid"/>
          <xsl:call-template name="propertyElt_s">
            <xsl:with-param name="node" select="$node"/>
            <xsl:with-param name="subject" select="$genid"/>
            <!-- this is just a placeholder... -->
            <xsl:with-param name="parentSubject" select="$parentSubject"/>
            <xsl:with-param name="parentPredicate" select="$parentPredicate"/>
            <xsl:with-param name="parentElement" select=".."/>
          </xsl:call-template>
          <xsl:call-template name="propAttr_s">
            <xsl:with-param name="subject" select="$genid"/>
          </xsl:call-template>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each>
  </xsl:template>
  <xsl:template name="propertyElt_s">
    <xsl:param name="subject"/>
    <xsl:param name="parentSubject"/>
    <xsl:param name="parentPredicate"/>
    <xsl:param name="node"/>
    <xsl:param name="parentElement"/>
    <!-- when subject is empty, it is an internal stuff; the local-name($node) may give out a Bag or a Sequence! -->
    <xsl:if test="$parentPredicate">
      <xsl:call-template name="statement">
        <xsl:with-param name="subject" select="$parentSubject"/>
        <xsl:with-param name="predicate" select="$parentPredicate"/>
        <xsl:with-param name="object" select="$subject"/>
        <xsl:with-param name="objectType" select="$uriReferenceType"/>
      </xsl:call-template>
    </xsl:if>
    <!-- [17] typedNode -->
    <xsl:if test='$node and (namespace-uri($node) != $rdfNS or local-name($node) != "Description")'>
      <!-- it is one of the rdf internal stuffs, ie, Bag, Sequence, or Alternate! -->
      <!--
      <xsl:call-template name="statement">
        <xsl:with-param name="subject" select="$subject"/>
        <xsl:with-param name="predicate" select='concat($rdfNS, "type")'/>
        <xsl:with-param name="object" select="concat(namespace-uri($node), local-name($node))"/>
        <xsl:with-param name="objectType" select="$uriReferenceType"/>
      </xsl:call-template>
      <xsl:choose>
        <xsl:when test="local-name($node) = 'Bag'"> a bag of the followings:</xsl:when>
        <xsl:when test="local-name($node) = 'Seq'"> a sequence of the followings:</xsl:when>
        <xsl:when test="local-name($node) = 'Alt'"> one of the followings:</xsl:when>
      </xsl:choose>
      -->
    </xsl:if>
    <!-- ================== -->
    <xsl:choose>
      <xsl:when test="$subject">
        <p class="resource">Information on <xsl:value-of select="$subject"/></p>
        <xsl:call-template name="describeResource">
          <xsl:with-param name="nodeName" select="$subject"/>
        </xsl:call-template>
      </xsl:when>
    </xsl:choose>
    <ul>
      <xsl:for-each select="*">
        <!-- [6] propertyElt -->
        <xsl:variable name="predicate" select="concat(namespace-uri(), local-name())"/>
        <xsl:variable name="stID" select="@rdf:ID"/>
        <!-- or just ID@@ -->
        <xsl:choose>
          <!-- [8] value -->
          <xsl:when test="text()[string-length(normalize-space())&gt;0] and *">
            <xsl:call-template name="badElement">
              <xsl:with-param name="problem" select='"text and subelements mixed in property value"'/>
            </xsl:call-template>
          </xsl:when>
          <xsl:when test="text()[string-length(normalize-space())&gt;0]">
            <!-- @@ barf if any attrs except ID -->
            <xsl:call-template name="statement">
              <!-- @@parameterize the template to call for each statement? -->
              <xsl:with-param name="stID" select="$stID"/>
              <xsl:with-param name="subject" select="$subject"/>
              <xsl:with-param name="predicate" select="$predicate"/>
              <xsl:with-param name="object">
                <xsl:copy-of select="text()"/>
              </xsl:with-param>
              <xsl:with-param name="objectType" select="$stringType"/>
              <xsl:with-param name="parentElement" select="local-name($parentElement)"/>
            </xsl:call-template>
          </xsl:when>
          <xsl:when test="*">
            <!-- @@ barf if any attrs except ID -->
            <xsl:call-template name="description_s">
              <xsl:with-param name="parentSubject" select="$subject"/>
              <xsl:with-param name="parentPredicate" select="$predicate"/>
              <!-- pass $stID as $parentID? -->
            </xsl:call-template>
          </xsl:when>
          <!-- @@parseLiteral and parseResource -->
          <xsl:when test="@rdf:resource or (namespace-uri()=$rdfNS and @resource)">
            <xsl:for-each select="text()[string-length(normalize-space())&gt;0]|*">
              <xsl:call-template name="badElement">
                <xsl:with-param name="problem" select='"propertyElt with resource attribute should be empty"'/>
              </xsl:call-template>
            </xsl:for-each>
            <xsl:variable name="resAttr" select='@*[local-name()="resource" and namespace-uri()=$rdfNS or namespace-uri(current()) = $rdfNS]'/>
            <xsl:call-template name="statement">
              <xsl:with-param name="stID" select="$stID"/>
              <xsl:with-param name="subject" select="$subject"/>
              <xsl:with-param name="predicate" select="$predicate"/>
              <xsl:with-param name="object" select="$resAttr"/>
              <xsl:with-param name="objectType" select="$uriReferenceType"/>
              <xsl:with-param name="parentElement" select="local-name($parentElement)"/>
            </xsl:call-template>
            <!-- [16] propAttr -->
            <xsl:call-template name="propAttr_s">
              <xsl:with-param name="subject" select="$resAttr"/>
            </xsl:call-template>
          </xsl:when>
          <xsl:otherwise>
            <!-- [16] propAttr -->
            <!--@@ idAttr, bagIdAttr -->
            <xsl:variable name="genid" select='concat("#,", generate-id())'/>
            <xsl:call-template name="propAttr_s">
              <xsl:with-param name="subject" select="$genid"/>
            </xsl:call-template>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:for-each>
    </ul>
    <xsl:for-each select="text()[string-length(normalize-space())&gt;0]">
      <xsl:call-template name="badStuff">
        <xsl:with-param name="expected" select='"description"'/>
      </xsl:call-template>
    </xsl:for-each>
  </xsl:template>
  <xsl:template name="propAttr_s">
    <xsl:param name="subject"/>
    <!-- @@expand w.r.t. base? -->
    <xsl:for-each select='@*[not ((local-name() = "about" or local-name() = "resource" or local-name() = "ID" or local-name() = "bagID" or local-name() = "aboutEach" or local-name() = "aboutEachPrefix") and (namespace-uri() = $rdfNS or namespace-uri(current()) = $rdfNS)) ]'>
      <xsl:call-template name="statement">
        <xsl:with-param name="subject" select="$subject"/>
        <xsl:with-param name="predicate" select="concat(namespace-uri(.), local-name(.))"/>
        <xsl:with-param name="object">
          <xsl:value-of select="."/>
        </xsl:with-param>
        <xsl:with-param name="objectType" select="$stringType"/>
      </xsl:call-template>
    </xsl:for-each>
  </xsl:template>
  <xsl:template name="statement">
    <xsl:param name="stID"/>
    <xsl:param name="subject"/>
    <!-- @@expand w.r.t. base? -->
    <xsl:param name="predicate"/>
    <xsl:param name="object"/>
    <xsl:param name="objectType"/>
    <xsl:param name="parentElement"/>
    <xsl:if test="$stID">
      <!-- reification, at least a little bit -->
      <xsl:call-template name="statement">
        <xsl:with-param name="subject" select='concat("#", $stID)'/>
        <xsl:with-param name="predicate" select='concat($rdfNS, "type")'/>
        <xsl:with-param name="object" select='concat($rdfNS, "Statement")'/>
        <xsl:with-param name="objectType" select="$uriReferenceType"/>
      </xsl:call-template>
      <xsl:call-template name="statement">
        <xsl:with-param name="subject" select='concat("#", $stID)'/>
        <xsl:with-param name="predicate" select='concat($rdfNS, "subject")'/>
        <xsl:with-param name="object" select="$subject"/>
        <xsl:with-param name="objectType" select="$uriReferenceType"/>
      </xsl:call-template>
      <xsl:call-template name="statement">
        <xsl:with-param name="subject" select='concat("#", $stID)'/>
        <xsl:with-param name="predicate" select='concat($rdfNS, "predicate")'/>
        <xsl:with-param name="object" select="$predicate"/>
        <xsl:with-param name="objectType" select="$uriReferenceType"/>
      </xsl:call-template>
      <xsl:call-template name="statement">
        <xsl:with-param name="subject" select='concat("#", $stID)'/>
        <xsl:with-param name="predicate" select='concat($rdfNS, "object")'/>
        <xsl:with-param name="object" select="$object"/>
        <xsl:with-param name="objectType" select="$objectType"/>
      </xsl:call-template>
    </xsl:if>
    <xsl:call-template name="finalOutput">
      <xsl:with-param name="subject" select="$subject"/>
      <xsl:with-param name="predicate" select="$predicate"/>
      <xsl:with-param name="object" select="$object"/>
      <xsl:with-param name="objectType" select="$objectType"/>
      <xsl:with-param name="parentElement" select="$parentElement"/>
    </xsl:call-template>
  </xsl:template>
  <xsl:template name="badStuff">
    <xsl:param name="expected"/>
    <xsl:message>expected 
    <xsl:value-of select="$expected"/>
    but got: [[
    <xsl:copy-of select="."/>
    ]]</xsl:message>
  </xsl:template>
  <xsl:template name="badElement">
    <xsl:param name="problem"/>
    <xsl:message>problem in &lt;<xsl:value-of select="name(.)"/>&gt;: 
    <xsl:value-of select="$problem"/>
    </xsl:message>
  </xsl:template>
  <!-- Overriding the default built in node: by default, text and attributes should be swallowed! -->
  <xsl:template match="text()|@*">
    <!--  <xsl:value-of select="."/> -->
  </xsl:template>
</xsl:stylesheet>
