<?xml version="1.0" encoding="UTF-8"?><?xar XSLT?>
<!-- 
 ============================================================== 
 DOCUMENTATION
 ============================================================== 
 
 Input: valid ISO 19575-3 document: a Schematron schema
 Output: valid TR 9537-11 fragment: an annex for an ISO Standard

This stylesheet converts a Schematron schema into an annex for
an ISO standard or technical report, using the TR 9537-11 schema.

* Titles become annex or clause titles
* Each pattern is a clause
* Within each pattern, all the assertions are presented in a numbered
list as constraints.
* Within each pattern, all the reports are gathered into a separate
numbered lists, as thing that an implementations should report
* Abstract rules may be used. These are repeated each time, with the <name>
 element acting correctly (for elements at least)
* A paragraph of documentation uses the plain <p> element. Other kinds of
blocks elements from TR9537-11 can be represented using the class attribute
on the <p> element. Warnings, list items, examples, and pre elements, 
in particular; consecutive list items will be wrapped in the appropriate
container; multi-paragraph warnings, list items, etc are not supported.
* Tables, images and definition lists are not supported.
* The Schematron phase mechanism can be used to generate conformance classes
or levels, by selecting patterns.
* The inline elements can be used with the <span> element by providing their
name in the class attribute, except for tables and artwork.
* The following Schematron features are not transformed: diagnostics, namespace
and query language.
* The following Schematron features are probably not useful: abstract patterns,
abstract rules 
* The @see attribute can be used for bibliographic references (to URLs) but it
will require hand correction to link to the proper bibliographic items, which 
are not generated by this converter.
  
-->  

<xsl:stylesheet version="1.0" 
   xmlns:sch="http://purl.oclc.org/dsdl/schematron" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  >

<!-- 
 ============================================================== 
 DECLARATIONS
 ============================================================== 
-->  
<xsl:output method="xml" omit-xml-declaration="no" standalone="yes" indent="yes" />

<!-- 
 ============================================================== 
 SCHEMA ELEMENT
 ============================================================== 
-->  
<xsl:template match="sch:schema">

   <annex normative="true"  id="schematron-derived-annex">
   
 <xsl:comment>May need xmlns="http://purl.oclc.org/dsdl/9573-11amd1/ns/structure/1.0"</xsl:comment>
   	<xsl:apply-templates select="sch:title" />
   	<clause id="schematron-derived-annex-intro">
   	<title>Introduction</title>
   	<xsl:apply-templates select="sch:p[not(preceding-sibling::sch:pattern)]" />
	<xsl:if test="sch:ns">
		<p>The following table lists the namespaces and typical prefixes.</p>
		<p><tabular frame="all">
			<tgroup cols="2">
			<thead>
				<row><entry>Prefix</entry><entry>Namespace IRI</entry></row>
            </thead>
            <tbody>		
   	   	   	   	<xsl:apply-templates select="sch:ns" />
   	   	   	</tbody>
   	   	   	</tgroup>
   	   	</tabular>
   	   	</p>
    </xsl:if>
    <xsl:if test="not(sch:ns)">
         <p>The constraints in this document apply to elements which are not in any namespace.</p>
    </xsl:if>
    </clause>
    <xsl:if test="sch:phase">
    	<clause id="schematron-derived-annex-conform">
    	<title>Conformance Profiles</title>
    	<p>The following clauses define named conformance profiles. Each profile specifies a subset of 
    	the constraints and reporting requirements.</p>
       	<xsl:apply-templates select="sch:phase" />
      </clause>
	</xsl:if>    
   	<xsl:apply-templates select="sch:phase" />
   	<xsl:apply-templates select="sch:pattern" /> 
   	<xsl:apply-templates select="sch:p[preceding-sibling::sch:pattern]" />
   </annex>
</xsl:template>

<!-- INCLUDE -->
<xsl:template match="sch:include[not(normalize-space(@href))]" priority="1">
		<xsl:message terminate="yes">Schema error: Empty href= attribute for include directive.</xsl:message>
</xsl:template>

<!-- Extend the URI syntax to allow # refererences -->
<xsl:template match="sch:include">
    <xsl:variable name="document-uri" select="substring-before(concat(@href,'#'), '#')"/>
    <xsl:variable name="fragment-id" select="substring-after(@href, '#')"/>
       
    <xsl:choose> 
       <xsl:when test="$fragment-id">
            <xsl:apply-templates select="document( $document-uri,/ )//sch:*[@id= $fragment-id ]"/>
		</xsl:when>
		<xsl:otherwise>
       		<xsl:apply-templates select="document( $document-uri,/ )/*"/>
       	</xsl:otherwise>
	</xsl:choose>
</xsl:template>


<!-- 
 ============================================================== 
 OTHER SCHEMA ELEMENTS
 ============================================================== 
-->  
<!-- ACTIVE -->
<xsl:template match="sch:active">
   <li><p><xref to="{@pattern}" />
    <xsl:if test="@see"><footnote>Refer <code><xsl:value-of select="@see"/></code>.
   <xsl:comment>Hand edit required to replace this with proper xref to bibliography!</xsl:comment></footnote></xsl:if>
   </p>
</li>
</xsl:template>

<!-- ASSERT and REPORT-->
<xsl:template match="sch:assert" mode="handle-asserts">
	<xsl:param name="context">UNAVAILABLE</xsl:param>
   <li><p><xsl:apply-templates >
 		<xsl:with-param name="a-context" select="$context" />
   	</xsl:apply-templates>
   		<xsl:if test="@see"><footnote>Refer <code><xsl:value-of select="@see"/></code>.
   		<xsl:comment>Hand edit required to replace this with proper xref to bibliography!</xsl:comment></footnote></xsl:if>
   </p></li>
</xsl:template>

<xsl:template match="sch:report" mode="handle-reports">
	<xsl:param name="context">UNAVAILABLE</xsl:param>
   <li><p><xsl:apply-templates >
 		<xsl:with-param name="a-context" select="$context" />
   	</xsl:apply-templates>
   		<xsl:if test="@see"><footnote>Refer <code><xsl:value-of select="@see"/></code>.
   		<xsl:comment>Hand edit required to replace this with proper xref to bibliography!</xsl:comment></footnote></xsl:if>
	</p></li>
</xsl:template>

<xsl:template match="sch:assert | sch:report " />

<!-- DIAGNOSTIC -->
<xsl:template match="sch:diagnostic"> 
</xsl:template>

<!-- DIAGNOSTICS -->
<!-- no diagnostics -->
<xsl:template match="sch:diagnostics"> 
</xsl:template>

<!-- DIR -->
<xsl:template match="sch:dir">
   <xsl:apply-templates />
</xsl:template>

<!-- EMPH -->
<xsl:template match="sch:emph">
   <strong><xsl:apply-templates /></strong>
</xsl:template>

<!-- EXTENDS -->
<xsl:template match="sch:extends" />



<!-- Handle asserts when a normal rule has an extension -->
<xsl:template match="sch:rule[not(@abstract='true')]/sch:extends" mode="handle-asserts">
   
   	<xsl:apply-templates select="//sch:rule[@abstract='true'][@id=current()/@rule]" mode="handle-asserts" >
   		<xsl:with-param name="context" select="../@context" />
   	</xsl:apply-templates>
</xsl:template>

<!-- Handle asserts when an abstract rule has an extension -->
<xsl:template match="sch:rule[@abstract='true']/sch:extends" mode="handle-asserts">
   <xsl:param name="context">UNKNOWN</xsl:param>
    <xsl:apply-templates select="//sch:rule[@abstract='true'][@id=current()/@rule]" mode="handle-asserts" >
 		<xsl:with-param name="context" select="$context" />
   	</xsl:apply-templates>
</xsl:template>


<!-- Handle reports when a normal rule has an extension -->
<xsl:template match="sch:rule[not(@abstract='true')]/sch:extends" mode="handle-reports">
   <xsl:apply-templates select="//sch:rule[@abstract='true'][@id=current()/@rule]" mode="handle-reports" >
   		<xsl:with-param name="context" select="../@context" />
   	</xsl:apply-templates>
</xsl:template>

<!-- Handle reports when an abstract rule has an extension -->
<xsl:template match="sch:rule[@abstract='true']/sch:extends" mode="handle-reports">
 <xsl:param name="context">UNKNOWN</xsl:param>
        <xsl:variable name="context" select="../@context" />
   <xsl:apply-templates select="//sch:rule[@abstract='true'][@id=current()/@rule]" mode="handle-reports" >
   		<xsl:with-param name="context" select="$context" />
   	</xsl:apply-templates>
</xsl:template>


<!-- XSL:KEY -->
<xsl:template match="xsl:key">
</xsl:template>

<!-- LET -->
<xsl:template match="sch:let">
</xsl:template>

<!-- NAME -->
<!-- Handle names in abstract rules -->
<xsl:template match="sch:name[ancestor::sch:rule[not(@abstract='true')]]" priority="3">
	<!-- not quite right. need to handle subject and name having explicit path -->
   <code><xsl:value-of select="../../@context"/></code>
</xsl:template>
 

<xsl:template match="sch:name[ancestor::sch:rule[not(@abstract='true')]][ancestor::sch:pattern[@abstract='true']]" priority="4">
	<!-- not quite right. need to handle subject and name having explicit path -->
   <code><i><xsl:value-of select="../../@context"/></i></code>
</xsl:template>
<xsl:template match="sch:name[ancestor::sch:pattern[@abstract='true']]" priority="2">
    <xsl:param name="a-context">MISSING</xsl:param>
	<!-- not quite right. need to handle subject and name having explicit path -->
   <code><i><xsl:value-of select="$a-context"/></i></code>
</xsl:template>


<xsl:template match="sch:name">
    <xsl:param name="a-context">MISSING</xsl:param>
	<!-- not quite right. need to handle subject and name having explicit path -->
   <code><xsl:value-of select="$a-context"/></code>
</xsl:template>



<!-- NS -->
<xsl:template match="sch:ns">
   <row><entry><xsl:value-of select="@prefix" /></entry>
   <entry><xsl:value-of select="@uri" /></entry></row>
</xsl:template>

<!-- P -->
<xsl:template match="sch:p[@class]" priority="1">   

	<!-- common case is that class = ol or ul need to become list items -->
   <xsl:choose>
   		<xsl:when test="@class='ul'">
   			<xsl:if test="not(preceding-sibling::sch:p[@class='ul'])">
   				<xsl:text disable-output-escaping="yes">&lt;ul&gt;</xsl:text>
   			</xsl:if>
   			<li><p><xsl:apply-templates />  	
   		    <xsl:if test="@see"><footnote>Refer <code><xsl:value-of select="@see"/></code>.
   		<xsl:comment>Hand edit required to replace this with proper xref to bibliography!</xsl:comment></footnote></xsl:if>
</p></li>  			
   			<xsl:if test="not(following-sibling::sch:p[@class='ul'])">
   				<xsl:text disable-output-escaping="yes">&lt;/ul&gt;</xsl:text>
   			</xsl:if>
   		</xsl:when>
   		
   		<xsl:when test="@class='ol'">
   			<xsl:if test="not(preceding-sibling::sch:p[@class='ol'])">
   				<xsl:text disable-output-escaping="yes">&lt;ol&gt;</xsl:text>
   			</xsl:if>
   			<li><p><xsl:apply-templates />
   	  		<xsl:if test="@see"><footnote>Refer <code><xsl:value-of select="@see"/></code>.
   		<xsl:comment>Hand edit required to replace this with proper xref to bibliography!</xsl:comment></footnote></xsl:if>
</p>
</li>
   			<xsl:if test="not(following-sibling::sch:p[@class='ol'])">
   				<xsl:text disable-output-escaping="yes">&lt;/ol&gt;</xsl:text>
   			</xsl:if>
   		</xsl:when>
   
   		<xsl:when test="@class='note'">
   		    <!-- only single para notes -->
   			<note><p><xsl:apply-templates/>
   			  		<xsl:if test="@see"><footnote>Refer <code><xsl:value-of select="@see"/></code>.
   		<xsl:comment>Hand edit required to replace this with proper xref to bibliography!</xsl:comment></footnote></xsl:if>
</p></note>
   		</xsl:when>
   		
   		<xsl:when test="@class='genwarn'or @class='warning' or @class='caution' or @class='remark'">
   		    <!-- only single para warnings -->
   			<warn format="{@class}"><p><xsl:apply-templates/>
   			  		<xsl:if test="@see"><footnote>Refer <code><xsl:value-of select="@see"/></code>.
   		<xsl:comment>Hand edit required to replace this with proper xref to bibliography!</xsl:comment></footnote></xsl:if>
</p></warn>
   		</xsl:when>
   		
   		<xsl:when test="@class='example'">
   		    <!-- only single para example -->
   			<example><p><xsl:apply-templates/></p></example>
   		</xsl:when>
   		
   		<xsl:when test="@class='pre'">
   		    <!-- only single para example -->
   			<pre xml:space="preserve"><xsl:apply-templates/></pre>
   		</xsl:when>
   		
   		<xsl:otherwise>
   			<p><xsl:comment><xsl:value-of select="@class"/></xsl:comment><xsl:apply-templates />
   			  		<xsl:if test="@see"><footnote>Refer <code><xsl:value-of select="@see"/></code>.
   		<xsl:comment>Hand edit required to replace this with proper xref to bibliography!</xsl:comment></footnote></xsl:if>
</p>
   		</xsl:otherwise>
   	</xsl:choose>	
</xsl:template>

<xsl:template match="sch:p">
   <p><xsl:apply-templates />
     		<xsl:if test="@see"><footnote>Refer <code><xsl:value-of select="@see"/></code>.
   		<xsl:comment>Hand edit required to replace this with proper xref to bibliography!</xsl:comment></footnote></xsl:if>
</p>
</xsl:template>
 

 
<!-- PATTERN -->

<xsl:template match="sch:pattern[@abstract='true']" priority="1"   >
   <clause id="{concat('schematron-derived-annex-', @id)}">
   <xsl:apply-templates select="sch:title"/>
   <xsl:apply-templates select="sch:p"/>
   <p>For each of the following parameter tables, the constraints below apply.</p>
   <note><p>The following names and values may be XPath expressions. <code>@</code> is
   selects an attribute name. <code>$</code> selects a parameter. </p></note>
   <ol>
   <xsl:for-each select="//sch:pattern[@is-a=current()/@id]">
       <li><p>
   		<tabular frame="all">
   			<tgroup cols="2">
   			<thead><row><entry>Parameter Name</entry><entry>Parameter Value</entry></row></thead>
   			<tbody>
   			<xsl:for-each select="sch:param">
   				<row><entry><code><i><xsl:value-of select="@name"/></i></code></entry>
   				<entry><xsl:value-of select="@value"/></entry>
   				</row>
   			</xsl:for-each>
   			</tbody>
   			</tgroup>
   		</tabular>
   		</p></li>
   </xsl:for-each>
   </ol>
   
    <xsl:if test="sch:rule/sch:assert">
         <p>To conform to this clause, a document should conform to the following constraints, 
         after substituting named parameters with the value above in each each case:</p>
   		<ol><xsl:apply-templates select="sch:rule[not(@abstract='true')]" mode="handle-asserts" /></ol>
    </xsl:if>
    <xsl:if test="sch:rule/sch:report">
     	<p>To conform to this clause, an application should report the following cases, 
         after substituting named parameters with the value above in each each case:</p>
   		<ol><xsl:apply-templates select="sch:rule[not(@abstract='true')]" mode="handle-reports" /></ol>
   </xsl:if> 
   </clause>
</xsl:template>
 
<xsl:template match="sch:pattern[@is-a]" priority="1"> 
</xsl:template>

<xsl:template match="sch:pattern">
   <clause id="{concat('schematron-derived-annex-', @id)}">
   <xsl:apply-templates select="sch:title"/>
   <xsl:apply-templates select="sch:p"/>
    <xsl:if test="sch:rule/sch:assert">
         <p>To conform to this clause, a document should conform to the following constraints:</p>
   		<ol><xsl:apply-templates select="sch:rule[not(@abstract='true')]" mode="handle-asserts" /></ol>
    </xsl:if>
    <xsl:if test="sch:rule/sch:report">
     	<p>To conform to this clause, an application should report the following cases:</p>
   		<ol><xsl:apply-templates select="sch:rule[not(@abstract='true')]" mode="handle-reports" /></ol>
   </xsl:if>
   </clause>
</xsl:template>

<!-- PHASE -->
<xsl:template match="sch:phase"> 
			<!-- Phases are turned into conformance settings -->
   		 
   			<clause id="{concat('schematron-derived-annex-conform-',  @id)}"><title><xsl:value-of select="@id"/></title>
   			    <p>A document conforms to this clause if the following clauses are 
   			    satisfied:</p>
   			    <ul>
   			    	<xsl:apply-templates />
   			    </ul>
   			</clause>  	 
</xsl:template>

<!-- RULE -->
<xsl:template match="sch:rule" />



<xsl:template match="sch:rule[@abstract='true']" mode="handle-asserts"> 
    <xsl:param name="context">UNKNOWN</xsl:param>
   <xsl:apply-templates select="sch:assert | sch:extends" mode="handle-asserts" >
   		<xsl:with-param name="context" select="$context" />
   	</xsl:apply-templates>
</xsl:template>

<xsl:template match="sch:rule[@abstract='true']" mode="handle-reports">
 <xsl:param name="context">UNKNOWN</xsl:param> 
   <xsl:apply-templates select="sch:report | sch:extends " mode="handle-reports" >
   		<xsl:with-param name="context" select="$context" />
   	</xsl:apply-templates>
</xsl:template>


<xsl:template match="sch:rule[not(@abstract='true')]" mode="handle-asserts"> 
   <xsl:apply-templates select="sch:assert | sch:extends" mode="handle-asserts" />
</xsl:template>

<xsl:template match="sch:rule[not(@abstract='true')]" mode="handle-reports"> 
      <xsl:apply-templates select="sch:report | sch:extends " mode="handle-reports" />
</xsl:template>

<!-- SPAN -->

<xsl:template match="sch:title/sch:span" priority="1">
   <code><xsl:apply-templates /></code>
</xsl:template>

<xsl:template match="sch:span">
   <xsl:element name="{@class}"><xsl:apply-templates /></xsl:element>
</xsl:template>

<!-- TITLE -->
<xsl:template match="sch:title">
   <title ><xsl:apply-templates /></title>
</xsl:template>

<!-- VALUE-OF -->

<xsl:template match="sch:value-of[ancestor::sch:pattern[@abstract='true']]" priority="1">  
   <code><i><xsl:value-of select="@select" /></i></code>
</xsl:template>

<xsl:template match="sch:value-of">
   <code><xsl:value-of select="@select" /></code>
</xsl:template>
 

</xsl:stylesheet>
