<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xsl:stylesheet [
<!-- this is used to make a special case for multiRef elements from 
     ruby soap services, as generated by Axis. The option is defined as
     an entity rather than a parameter so we can use it in a match pattern.
     This allows the Axis specific code to be reduced to a single template
     which can easily be removed. See "evil hack" below
-->


  <!ENTITY treat-multirefs "yes">
]>

<xsl:stylesheet 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:env="http://www.w3.org/2003/05/soap-envelope"
  xmlns:enc="http://www.w3.org/2003/05/soap-encoding"
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:ns1="urn:rubysoapservices"
  xmlns:ruby="urn:rubysoapservices"
  version="1.0">


  <xsl:param name="body-namespace-prefix" select="'n2'"/>
  <xsl:param name="body-namespace-uri" select="'http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.1'"/>



  <xsl:output indent="yes"/>

  <xsl:template match="/">
    <rdf:RDF>
       <xsl:apply-templates select="env:Body"/>
    </rdf:RDF>
  </xsl:template>

   <xsl:template match="env:Body">
   
      <xsl:apply-templates select="@*|node()"/>
 
 </xsl:template>

  <!-- ####### AXIS specific ########################################-->
  <!-- 2 evil hacks below -->
  <!-- nikki - 
  A SOAP BODY "begins" WITH AN EDGE (or multiple edges)
   
   SOAP encoding of data permits the situation where "An edge MAY have only a terminating graph node, that is be 
   inbound only" [http://www.w3.org/TR/soap12-part2/]
   
   Working with what Axis returns us, we will in this case simply wrap the node named rubyQueryResponse
   in an rdf:description element in order to produce valid RDF. 
  
   A more generic XSLT stylesheet would perhaps specify that the user supply a parameter indicating the
   element from which to "start" - ie the first element in the soap body to be treated as an *edge*.
   And "wrapped" around this edge there can therefore be an rdf:Description element, in order to produce
   valid RDF.-->
 

 <xsl:template match="ns1:rubyQueryResponse"> 
    <rdf:Description>   
       
          <xsl:element name="rubyQueryResponse" namespace="urn:rdf2soap">
      
      <xsl:apply-templates/>
      	</xsl:element>
   </rdf:Description>
  </xsl:template>

  
  <!-- We assume that use of the multiRef accessor is Axis-specific (& pertains to the Axis implementors'
  interpretation of the Soap Encoding data model). We map multiref accessors to RDF typed elements 
  (as opposed to rdf:Description elements + rdf:Type elements),
  extracting the type from the muliRef element's xsi:type attribute value. These typed elements are given
  an rdf:nodeID attribute which takes the appropriate value of the multiref id.
  -->

   
  <xsl:template match="multiRef['&treat-multirefs;' = 'yes']">
 
 <rdf:Description>
    
     
     <xsl:if test="@enc:id">
	  <xsl:attribute name="rdf:nodeID">
	    <xsl:value-of select="@enc:id"/>
	  </xsl:attribute>
	</xsl:if>
		 <rdf:type rdf:resource="ruby:{substring-after(@xsi:type,':')}"/>
		<xsl:apply-templates/> 
 

  
  </rdf:Description>
  </xsl:template>
  
  
  
  <!-- ##############################################################-->
  
  <xsl:template match="*">
    <!-- in SOAP1.2 elements can be in no namespace, but not in RDF -->
    <!-- so we use a dummy namespace in that case -->
    <xsl:variable name="ns">
       <xsl:choose>
	<xsl:when test="namespace-uri()=''">urn:rdf2soap</xsl:when>
	<xsl:otherwise><xsl:value-of select="namespace-uri()"/></xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <xsl:element name="{name()}" namespace="{$ns}">
      <xsl:apply-templates select="@*"/>

     
      <xsl:if test="* or @xsi:type">
	
	  
	   <xsl:if test="@enc:id">
	    <xsl:attribute name="rdf:nodeID">
	      <xsl:value-of select="@enc:id"/>
	    </xsl:attribute>
	  </xsl:if>
	  
	  <xsl:if test="@xsi:type and *">
	    	  <rdf:Description>
	    <!-- if there's an xsi:type on an element that has
		 child elements then we assume it's a complex type
		 and thus generate an rdf:type -->
	    <rdf:type rdf:resource="{@xsi:type}"/>
	    
	    	</rdf:Description>
	  </xsl:if>
	  <xsl:if test="@xsi:type and text()">

	    <!-- if there's an xsi:type element attribute that has no
		 child elements then we assume it's an WXS simple type
		 and thus generate an rdf:datatype -->
	      <xsl:attribute name="rdf:datatype">http://www.w3.org/2001/XMLSchema#<xsl:value-of select="substring-after(@xsi:type,':')"/></xsl:attribute>

	 </xsl:if>
	 
	 
	 <xsl:if test="@xsi:nil='true'">
	    <!-- if there's an xsi:nil element attribute, this represents a graph edge that does not terminate in a graph node
	    and is modelled in RDF as an edge pointing to a b-node
	    -->
	 	<rdf:Description>
		</rdf:Description>
	 </xsl:if>	
	 
	  <xsl:apply-templates/>
	
      </xsl:if>

    </xsl:element>
  </xsl:template>

  <xsl:template match="@*"/>



  <xsl:template match="@enc:ref">
    <xsl:attribute name="rdf:nodeID">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:template>

<!-- 
 <xsl:template match="ns1:rubyQueryResponse">
    <rdf:Description>   
      <xsl:apply-templates/>
   </rdf:Description>
  </xsl:template>
  
-->
  
</xsl:stylesheet>

