<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="/parts/xsltdoc.xsl" type="text/xsl" media="screen"?>
<!DOCTYPE xsl:stylesheet [
 <!ENTITY atomrdfns  'http://www.w3.org/2005/Atom#'>
 <!ENTITY nsxml  'http://www.w3.org/XML/1998/namespace'>
]>
<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="&atomrdfns;"
  xmlns:atom="&atomrdfns;"
  xmlns:atoms="http://www.w3.org/2005/Atom"
  xmlns:rss="http://purl.org/rss/1.0/"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:foaf="http://xmlns.com/foaf/0.1/"
  xmlns:h="http://www.w3.org/1999/xhtml"
  exclude-result-prefixes="atoms h"
>

 <xsl:template name="_doas_description">
  <rdf:RDF xmlns="http://purl.org/net/ns/doas#">
   <rdf:Description rdf:about="">
    <title>Atom to RDF stylesheet</title>
    <description>This stylesheet is designed to convert Atom1.0 file to a valid RDF (with some RSS 1.0 terms). Tentative namespace URI for Atom-RDF is &atomrdfns;.</description>
    <author rdf:parseType="Resource">
     <name>Masahide Kanzaki</name>
     <mbox rdf:resource="mailto:webmaster@kanzaki.com"/>
    </author>
    <created>2005-07-23</created>
    <release rdf:parseType="Resource">
     <revision>0.42</revision>
     <created>2007-11-27</created>
    </release>
    <rights>(c) 2005 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 indent="yes" method="xml"/>

 <xsl:template match="/">
 <!--** provide wrapper rdf:RDF element with some root attributes such ans xml:base -->
  <rdf:RDF>
   <xsl:apply-templates select="atoms:feed/@*"/>
   <xsl:apply-templates select="atoms:feed"/>
  </rdf:RDF>
 </xsl:template>

 <xsl:template match="*">
 <!--** catch all element nodes template. setup namespace appropriately-->
  <xsl:variable name="ns" select="namespace-uri()"/>
  <xsl:element name="{name()}" namespace="{$ns}">
   <xsl:apply-templates select="@*"/>
   <xsl:choose>
    <xsl:when test="*"><xsl:apply-templates select="*"/></xsl:when>
    <xsl:otherwise><xsl:value-of select="."/></xsl:otherwise>
   </xsl:choose>
  </xsl:element>
 </xsl:template>

 <xsl:template match="atoms:*">
 <!--** catch all atom element nodes template. Atom elements will be transferd default namespace element (in case some feeds use different prefix than standard atoms: or default : -->
  <xsl:element name="{local-name()}">
   <xsl:apply-templates select="@*"/>
   <xsl:choose>
    <xsl:when test="*"><xsl:apply-templates select="*"/></xsl:when>
    <xsl:otherwise><xsl:value-of select="."/></xsl:otherwise>
   </xsl:choose>
  </xsl:element>
 </xsl:template>

 <xsl:template match="h:*">
 <!--** bare XHTML causes troubles -->
  <_bareXhtml rdf:parseType="Literal">
   <xsl:copy-of select="."/>
  </_bareXhtml>
 </xsl:template>

 <xsl:template match="@*">
  <!--** catch all attribute nodes. Checks for ns prefix-->
  <xsl:variable name="pfx">
   <xsl:if test="not(contains(name(),':'))">atom:</xsl:if>
  </xsl:variable>
  <xsl:attribute name="{$pfx}{name()}">
   <xsl:value-of select="."/>
  </xsl:attribute>
 </xsl:template>

 <xsl:template match="atoms:*[@type]">
  <!--** Atom text construct types. Steps:-->
  <xsl:element name="{local-name()}">
   <!--xsl:apply-templates select="@xml:*"/-->
   <xsl:apply-templates select="@*[namespace-uri()='&nsxml;']"/>
   <xsl:choose>
    <!--@ If @type=xhtml, copy all child nodes and treat content as XMLLiteral (content must have single XHTML div element, ala spec)... but since there are many missing div errors, just value-of for that case. -->
    <xsl:when test="@type='xhtml'">
     <xsl:attribute name="rdf:parseType">Literal</xsl:attribute>
     <xsl:choose>
      <xsl:when test="*"><xsl:copy-of select="*"/></xsl:when>
      <xsl:otherwise><xsl:comment>missing div element error</xsl:comment><xsl:value-of select="."/></xsl:otherwise>
     </xsl:choose>
    </xsl:when>
    <!--@ If @type=text|html, just copy the content (html tags are escaped with entity references by definition -->
    <xsl:when test="@type='text' or @type='html' or starts-with(@type,'text/')">
     <xsl:value-of select="."/>
    </xsl:when>
    <!--@ Otherwise, this is simply atom:content:
     If @src, it is a link to an external resource-->
    <xsl:when test="@src">
     <xsl:attribute name="rdf:resource"><xsl:value-of select="@src"/></xsl:attribute>
     <xsl:attribute name="dc:format"><xsl:value-of select="@type"/></xsl:attribute>
    </xsl:when>
    <!--@ If @type is xml (and no @src), treat content as XMLLiteral.-->
    <xsl:when test="contains(@type,'xml')">
     <xsl:attribute name="rdf:parseType">Literal</xsl:attribute>
     <xsl:copy-of select="*"/>
    </xsl:when>
    <!--@ otherwise, just copy content (if @type, content is base64, otherwise, treat as if @type=text)-->
    <xsl:otherwise>
     <xsl:value-of select="."/>
    </xsl:otherwise>
   </xsl:choose>
  </xsl:element>
 </xsl:template>


 <xsl:template match="atoms:feed">
 <!--** For atoms:feed, treat it as rss:channel, find its uri, set rdf:type to &atomrdfns;feed, add some RSS1.0 flavor, and treat all other child element nodes.-->
  <rss:channel>
   <xsl:apply-templates select="atoms:link[@rel='self']"/>
   <rdf:type rdf:resource="&atomrdfns;feed"/>
   <xsl:apply-templates select="atoms:link[@rel='alternate']"/>
   <xsl:apply-templates select="atoms:link[@rel != 'self' and @rel != 'alternate']"/>
   <xsl:apply-templates select="atoms:link[not(@rel)]"/>
   <!--xsl:call-template name="rssify"/-->
   <xsl:apply-templates select="*[local-name() != 'link']"/>
  </rss:channel>
 </xsl:template>

 <xsl:template match="atoms:entry">
  <!--** For atoms:entry, treat it as property and give corresponding rss:item node element so that construct proper RDF graph.-->
  <xsl:element name="{local-name()}">
   <rss:item>
    <xsl:apply-templates select="atoms:link[@rel='alternate']"/>
    <xsl:apply-templates select="atoms:link[not(@rel)]"/>
    <xsl:apply-templates select="atoms:link[@rel != 'alternate']"/>
    <!--xsl:call-template name="rssify"/-->
    <xsl:apply-templates select="*[local-name() != 'link']"/>
   </rss:item>
  </xsl:element>
 </xsl:template>

 <xsl:template match="atoms:author|atoms:source">
  <!--** For some atoms:* elements, treat it as parseType Resource so that construct proper RDF graph.-->
  <xsl:element name="{local-name()}">
   <xsl:attribute name="rdf:parseType">Resource</xsl:attribute>
   <xsl:apply-templates select="*"/>
  </xsl:element>
 </xsl:template>

 <xsl:template match="atoms:email">
  <!--** For atoms:email elements, also generates foaf:mbox so that the auther be foaf:Person, and can be identified by mailto: uri.-->
  <xsl:element name="{local-name()}">
   <xsl:value-of select="."/>
  </xsl:element>
  <foaf:mbox rdf:resource="mailto:{.}"/>
 </xsl:template>

 <xsl:template match="atoms:generator">
  <!--** For atoms:* elements that have both property attirbute(s) and literal content, generate rdf:value attribute to serve content text. -->
  <xsl:element name="{local-name()}">
   <xsl:apply-templates select="@*"/>
   <xsl:attribute name="rdf:value"><xsl:value-of select="."/></xsl:attribute>
  </xsl:element>
 </xsl:template>

 <xsl:template match="atoms:link[@href]">
  <!--** For atoms:link, the element will be treated differentlly according to its 'rel' attribute and context. Steps:-->
  <xsl:choose>
   <!--@ If @rel=self, then it's parent's rdf:about-->
   <xsl:when test="@rel='self'">
    <xsl:attribute name="rdf:about"><xsl:value-of select="@href"/></xsl:attribute>
   </xsl:when>
   <!--@ If @rel=alternate, if the link is child of 'entry' then it is entry's rdf:about, otherwise it is atom:alternate.-->
   <xsl:when test="@rel='alternate'">
    <xsl:choose>
     <xsl:when test="local-name(../.)='entry' and position()=1">
      <xsl:attribute name="rdf:about"><xsl:value-of select="@href"/></xsl:attribute>
     </xsl:when>
     <xsl:otherwise>
      <alternate rdf:resource="{@href}"/>
      <!-- could be atom:link -->
     </xsl:otherwise>
    </xsl:choose>
   </xsl:when>
   <!--@ if it has no @rel and is only link then then it's parent's rdf:about-->
   <xsl:when test="not(@rel) and not(preceding-sibling::atoms:link) and not(following-sibling::atoms:link)">
    <xsl:attribute name="rdf:about"><xsl:value-of select="@href"/></xsl:attribute>
   </xsl:when>
   <!--@ if @rel=related, then dc:relation-->
   <xsl:when test="@rel='related'">
    <dc:relation rdf:resource="{@href}"/>
   </xsl:when>
   <!--@ if it has other @rel, then @rel is property name-->
   <xsl:when test="@rel">
    <xsl:element name="{@rel}">
     <xsl:attribute name="rdf:resource"><xsl:value-of select="@href"/></xsl:attribute>
    </xsl:element>
   </xsl:when>
   <!--@ otherwise, just atoms:link with @href for rdf:resource-->
   <xsl:otherwise>
    <xsl:element name="{local-name()}">
     <xsl:attribute name="rdf:resource"><xsl:value-of select="@href"/></xsl:attribute>
    </xsl:element>
   </xsl:otherwise>
  </xsl:choose>
 </xsl:template>
 
 <xsl:template name="rssify">
 <!--** Generates rss:title, dc:date and rss:description for RSS1.0 reader .. might be redundant. -->
  <rss:title><xsl:value-of select="atoms:title"/></rss:title>
  <dc:date><xsl:value-of select="atoms:updated"/></dc:date>
  <xsl:if test="atoms:summary|atoms:subtitle">
   <rss:description><xsl:value-of select="atoms:summary|atoms:subtitle"/></rss:description>
  </xsl:if>
 </xsl:template>

</xsl:stylesheet>
