<?xml version="1.0" encoding="UTF-8"?>
<!-- xml2rdf22.xsl       XSLT stylesheet to transform XML into RDF/XML

     Version             2.2  (2008-09-23)
     Changes to V2.1     distinction of attributes from elements by a triple
                         with rdf:type predicate to an xsl:attribute object
     Web page            http://www.gac-grid.org/project-products/Software/XML2RDF.html
     Usage               xsltproc xml2rdf22.xsl file.xml
     Author              Frank Breitling (fbreitling at aip.de)
     Copyright 2008      AstroGrid-D (http://www.gac-grid.org/) 
 
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
 
         http://www.apache.org/licenses/LICENSE-2.0
 
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
 -->

<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:xs="http://www.w3.org/2001/XMLSchema#">

       <xsl:strip-space elements="*"/>
       <xsl:output method="xml" indent="yes"/>

       <!-- Begin RDF document -->
       <xsl:template match="/">
              <xsl:element name="rdf:RDF">
                     <xsl:element name="{name(child::node())}"
                            namespace="{namespace-uri(child::node())}">
                            <xsl:attribute name="rdf:about"/>
                            <xsl:attribute name="xs:add"/>                            
                            <xsl:apply-templates select="*/@*|*/node()"/>
                     </xsl:element>
              </xsl:element>
       </xsl:template>

       <!-- Turn elements into RDF tiples by keeping their namespaces.
            Avoid blank nodes by using an rdf:Description element with a unique
            URI for each subject composed by the @uid and all acestors nodes  -->
       <xsl:param name="subjectname"/>

       <xsl:template match="*">

              <!-- Create unique resource names -->
              <xsl:variable name="newsubjectname">
                     <xsl:if test="$subjectname=''">
                            <xsl:text>#</xsl:text>
                            <!--xsl:value-of select="substring-after(/*/@uid,'http://')"/-->
                     </xsl:if>
                     <xsl:value-of select="$subjectname"/>
                     <xsl:value-of select="name()"/>
                     <xsl:variable name="number">
                            <xsl:number/>
                     </xsl:variable>
                     <xsl:if test="$number > 1">
                            <xsl:number/>
                     </xsl:if>
              </xsl:variable>

              <!--xsl:copy-->
              <xsl:element name="{name()}" namespace="{namespace-uri()}">
                     <xsl:choose>
                            <xsl:when test="count(./@*)+count(*) > 0">
                                   <xsl:element name="{name()}" namespace="{namespace-uri()}">
                                          <xsl:attribute name="rdf:about">
                                                 <xsl:value-of select="$newsubjectname"/>
                                          </xsl:attribute>
                                          <xsl:apply-templates select="@*|node()">
                                                 <xsl:with-param name="subjectname"
                                                  select="concat($newsubjectname,'/')"/>
                                          </xsl:apply-templates>
                                   </xsl:element>
                            </xsl:when>
                            <xsl:otherwise>
                                   <xsl:apply-templates select="@*|node()">
                                          <xsl:with-param name="subjectname"
                                                 select="$newsubjectname"/>
                                   </xsl:apply-templates>
                            </xsl:otherwise>
                     </xsl:choose>
              </xsl:element>
              <!--/xsl:copy-->
       </xsl:template>

       <!-- Convert any attribute into an element and apply namespace-uri -->
       <xsl:template match="@*" name="attributes">
              <xsl:variable name="ns">
                     <!-- If attribute doesn't have a namespace use element namespace -->
                     <xsl:choose>
                            <xsl:when test="namespace-uri()=''">
                                   <xsl:value-of select="namespace-uri(..)"/>
                            </xsl:when>
                            <xsl:otherwise>
                                   <xsl:value-of select="namespace-uri()"/>
                            </xsl:otherwise>
                     </xsl:choose>
              </xsl:variable>
              <xsl:element name="xs:attribute">
                     <xs:attribute rdf:about="{$subjectname}attribute">
                            <!--xsl:element name="{name()}" namespace="{$ns}"-->
                            <xsl:element name="{name()}" namespace="{namespace-uri(..)}">
                                   <xsl:value-of select="."/>
                            </xsl:element>
                     </xs:attribute>
              </xsl:element>
       </xsl:template>

       <!-- Enclose text() in a rdf:value tag, if its paraent cotains
              attributes or the text() has siblings (i.e. mixed content)-->
       <xsl:template match="text()">
              <xsl:choose>
                     <xsl:when test="count(../@*)+count(../*) > 0">
                            <xsl:element name="rdf:value">
                                   <xsl:value-of select="."/>
                            </xsl:element>
                     </xsl:when>
                     <xsl:otherwise>
                            <xsl:value-of select="."/>
                     </xsl:otherwise>
              </xsl:choose>
       </xsl:template>

</xsl:stylesheet>

