<?xml-stylesheet href="/parts/xsltdoc.xsl" type="text/xsl" media="screen"?>
<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:h="http://www.w3.org/1999/xhtml"
  xmlns:foaf="http://xmlns.com/foaf/0.1/"
  xmlns:xfn="http://gmpg.org/xfn/1#"
  xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:dcterms="http://purl.org/dc/terms/"
>
<!-- with help by ldodds -->
<!-- : dcterms:created ""; dcterms:modified "" . -->

 <xsl:variable name="_doas" select="document('')//rdf:Description[1]"/>

 <xsl:template name="_doas_description">
  <rdf:RDF xmlns="http://purl.org/net/ns/doas#">
   <rdf:Description rdf:about="">
    <title>XFN to RDF convertor stylesheet</title>
    <description>This stylesheet is designed to extract metadata from XFN rel attributes in an XHTML document.</description>
    <author rdf:parthType="Resource">
     <name>Masahide Kanzaki</name>
     <mbox rdf:resource="mailto:webmaster@kanzaki.com"/>
    </author>
    <contributor rdf:parthType="Resource">
     <name>Leigh Dodds</name>
     <homepage rdf:resource="http://www.ldodds.com/"/>
    </contributor>
    <created>2004-03-03</created>
    <release rdf:parthType="Resource">
     <revision>0.80</revision>
     <created>2004-03-04</created>
    </release>
    <rights>(c) 2004 by the author, copyleft under GPL</rights>
    <license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/"/>
   </rdf:Description>
  </rdf:RDF>
 </xsl:template>

 <xsl:output method="xml" indent="yes"/>
 <xsl:param name="xmlfile"/>

 <xsl:variable name="xfnrel" select="'|acquaintance|friend|met|co-worker|colleague|co-resident|neighbor|child|parent|sibling|spouse|muse|crush|date|sweetheart|'"/>

 <xsl:template match="/">
  <!--** Triggers template. Set a PI to link XSLT stylesheet, and call template to proc html. -->
  <xsl:processing-instruction name="xml-stylesheet"> href="http://www.kanzaki.com/works/2004/misc/xfn-view.xsl" type="text/xsl"</xsl:processing-instruction>
  <xsl:apply-templates select="h:html"/>
 </xsl:template>

 <xsl:template match="h:html">
  <!--** Main template to process html. Steps: -->
  <rdf:RDF>
   <!--@ Generates a foaf:person for the document author. -->
   <foaf:Person>
    <xsl:call-template name="who">
     <xsl:with-param name="h" select="./h:head"/>
    </xsl:call-template>
   <!--@ Call templates to find friends. -->
    <xsl:apply-templates select="h:body//h:a[@rel]"/>
   </foaf:Person>
   <!--@ Generates a document information if available. -->
   <xsl:if test="$xmlfile">
    <rdf:Description rdf:about="">
     <dc:source rdf:resource="{$xmlfile}"/>
    </rdf:Description>
   </xsl:if>
  </rdf:RDF>
 </xsl:template>

 <xsl:template match="h:a[@rel]">
  <!--** Find instances of <a rel=...> and caool template xfn. -->
  <xsl:call-template name="xfn">
   <xsl:with-param name="ref" select="@href"/>
   <xsl:with-param name="props" select="concat(@rel,' ')"/>
  </xsl:call-template>
 </xsl:template>

 <xsl:template name="xfn">
  <!--** Find friend relations from <a rel=...> recursively. Steps: -->
  <xsl:param name="ref"/>
  <xsl:param name="props"/>
  <xsl:param name="nodeID"/>
  <!--@ Get the first @rel value as $p. -->
  <xsl:variable name="p" select="substring-before($props,' ')"/>
  <xsl:variable name="rest" select="substring-after($props,' ')"/>
  <xsl:if test="contains($xfnrel,concat('|',$p,'|'))">
  <!--@ If $p is one of XFN properties, then -->
   <xsl:element name="xfn:{$p}">
    <xsl:choose>
     <!--@ if already has nodeID, it is about that person hence refere to the node, -->
     <xsl:when test="$nodeID">
      <xsl:attribute name="rdf:nodeID">
       <xsl:value-of select="$nodeID"/>
      </xsl:attribute>
     </xsl:when>
     <!--@ otherwise it's a new friend and generate foaf:Person. -->
     <xsl:otherwise>
      <foaf:Person rdf:nodeID="{generate-id(.)}">
       <foaf:name><xsl:value-of select="."/></foaf:name>
       <foaf:homepage rdf:resource="{$ref}"/>
      </foaf:Person>
     </xsl:otherwise>
     </xsl:choose>
   </xsl:element>
  </xsl:if>
  <!--@ If there is more @rel value, then call this template recursively. -->
  <xsl:if test="$rest">
   <xsl:call-template name="xfn">
    <xsl:with-param name="ref" select="$ref"/>
    <xsl:with-param name="props" select="$rest"/>
    <xsl:with-param name="nodeID" select="generate-id(.)"/>
   </xsl:call-template>
  </xsl:if>
 </xsl:template>

 <xsl:template name="who">
  <!--** Find the document author's properties. -->
  <xsl:param name="h"/>
  <xsl:variable name="mbox">
   <xsl:choose>
    <xsl:when test="$h/h:link[@rev='made']"><xsl:value-of select="$h/h:link[@rev='made']/@href"/></xsl:when>
    <xsl:when test="count(h:body//h:a[starts-with(@href,'mailto:')])=1"><xsl:value-of select="h:body//h:a[starts-with(@href,'mailto:')]/@href"/></xsl:when>
   </xsl:choose>
  </xsl:variable>
  <xsl:if test="not($mbox='')">
   <foaf:mbox rdf:resource="{$mbox}"/>
  </xsl:if>
  <xsl:if test="$h/h:meta[@name='author']">
   <foaf:name><xsl:value-of select="$h/h:meta[@name='author']/@content"/></foaf:name>
  </xsl:if>
  <xsl:if test="$h/h:meta[@name='ICBM']">
   <foaf:based_near rdf:parseType="Resource">
    <geo:lat><xsl:value-of select="substring-before($h/h:meta[@name='ICBM']/@content,',')"/></geo:lat>
    <geo:long><xsl:value-of select="substring-after($h/h:meta[@name='ICBM']/@content,',')"/></geo:long>
   </foaf:based_near>
  </xsl:if>
  <xsl:if test="$xmlfile">
   <foaf:made rdf:resource="{$xmlfile}"/>
  </xsl:if>
 </xsl:template>

</xsl:stylesheet>
