D.3 Schematron Schema
The corresponding Schematron schema is:
<!--  
       (c) International Organization for Standardization 2005. 
       Permission to copy in any form is granted for use with conforming 
       SGML systems and applications as defined in ISO 8879, 
       provided this notice is included in all copies.
 -->
 
<sch:schema 
    xmlns:sch="http://purl.oclc.org/dsdl/schematron" 
    xml:lang="en" >
    
    <sch:title>Schema for Schematron Validation Report Language</sch:title>
    
    <sch:p>The Schematron Validation Report Language is a simple language 
        for implementations to use to compare their conformance. It is 
        basically a list of all the assertions that fail when validating 
        a document, in any order, together with other information such 
        as which rules fire.
    </sch:p>
    <sch:p>This schema can be used to validate SVRL documents, and provides
        examples of the use of abstract rules and abstract patterns.</sch:p>
    
    <sch:pattern>
        <sch:title>Elements</sch:title>

        <!--Abstract Rules -->
        <sch:rule abstract="true" id="second-level">
            <sch:assert test="../schematron-output">
                The <sch:name/> element is a child of schematron-output.
            </sch:assert>
        </sch:rule>
        
        <sch:rule abstract="true" id="childless">
            <sch:assert test="count(*)=0"> 
                The <sch:name/> element should not contain any elements.
            </sch:assert>
        </sch:rule>

        <sch:rule abstract="true" id="empty">
            <sch:extends rule="childless" />
            <sch:assert test="string-length(space-normalize(.)) = 0">
                The <sch:name/> element should be empty.
            </sch:assert>
        </sch:rule>
        
        <!-- Rules-->
        <sch:rule context="schematron-output">
            <sch:assert test="not(../*)">
                The <sch:name/> element is the root element.
            </sch:assert>
            <sch:assert 
                test="count(text) + count(ns) + count(active-pattern) +
                    count(fired-rule) + count(failed-assert) +
                    count(successful-report) = count(*)">
                <sch:name/> may only contain the following elements: 
                text, ns, active-pattern, fired-rule, failed-assert 
                and successful-report.
            </sch:assert>
            <sch:assert test="active-pattern">
                <sch:name/> should have at least one active pattern.
            </sch:assert>
        </sch:rule>
        
        <sch:rule context="text">
            <sch:extends rule="childless" />
        </sch:rule>
        
        <sch:rule context="diagnostic-reference">
            <sch:extends rule="childless" />
            <sch:assert test="string-length(@diagnostic) &gt; 0">
                <sch:name/> should have a diagnostic attribute, 
                giving the id of the diagnostic.
            </sch:assert>
        </sch:rule>
        
        <sch:rule context="ns">
            <sch:extends rule="second-level" />
            <sch:extends rule="empty" />
            <sch:assert 
                test="following-sibling::active-pattern or following-sibling::ns"> 
                A <sch:name/> comes before an active-pattern or another 
                ns element.
            </sch:assert>
        </sch:rule>
        
        <sch:rule context="active-pattern">
            <sch:extends rule="second-level" />
            <sch:extends rule="empty" />
        </sch:rule>
        
        <sch:rule context="fired-rule">
            <sch:extends rule="second-level" />
            <sch:extends rule="empty" />
            <sch:assert 
                test="preceding-sibling::active-pattern |
                    preceding-sibling::fired-rule |
                    preceding-sibling::failed-assert |
                    preceding-sibling::successful-report">
                A <sch:name/> comes after an active-pattern, an empty 
                fired-rule, a failed-assert or a successful report.
            </sch:assert>
            <sch:assert test="string-length(@context) &gt; 0">
                The <sch:name/> element should have a context attribute 
                giving the current context, in simple XPath format.
            </sch:assert> 
        </sch:rule>
        
        <sch:rule context="failed-assert | successful-report">
            <sch:extends rule="second-level" />
            <sch:assert 
                test="count(diagnostic-reference) + count(text) = count(*)"> 
                The <sch:name/> element should only contain a text element 
                and diagnostic reference elements.
            </sch:assert>
            <sch:assert test="count(text) = 1"> 
                The <sch:name/> element should only contain a text element.
            </sch:assert>
            <sch:assert test="preceding-sibling::fired-rule |
                preceding-sibling::failed-assert |
                preceding-sibling::successful-report"> 
                A <sch:name/> comes after a fired-rule, a failed-assert or a
                successful-report.
            </sch:assert>
        </sch:rule>
        
        <!-- Catch-all rule-->
        <sch:rule context="*">
            <sch:report test="true">
                An unknown <sch:name/> element has been used.
            </sch:report>
        </sch:rule>
    </sch:pattern>
    
    <sch:pattern>
        <sch:title>Unique Ids</sch:title>
        
        <sch:rule context="*[@id]">
            <sch:assert test="not(preceding::*[@id=current()/@id][1]"> 
                Id attributes should be unique in a document.
            </sch:assert>
        </sch:rule>
    </sch:pattern>
    
    <sch:pattern abstract="true" id="requiredAttribute">
        <sch:title>Required Attributes</sch:title>
        
        <sch:rule context=" $context ">
            <sch:assert test="string-length( $attribute ) &gt; 0">
                The <sch:name/> element should have a 
                <sch:value-of select="$attribute /name()" /> attribute.
            </sch:assert> 
        </sch:rule>
    </sch:pattern>
    
    <sch:pattern is-a="requiredAttribute">
        <sch:param name="context" value="diagnostic-reference" />
        <sch:param name="attribute" value="@diagnostic" />
    </sch:pattern>    
    
    <sch:pattern is-a="requiredAttribute">
        <sch:param name="context" value="failed-assert or successful-report" />
        <sch:param name="attribute" value="@location" />
    </sch:pattern>    
    
    <sch:pattern is-a="requiredAttribute">
        <sch:param name="context" value="failed-assert or successful-report" />
        <sch:param name="attribute" value="@test" />
    </sch:pattern>    

    <sch:pattern is-a="requiredAttribute">
        <sch:param name="context" value="ns" />
        <sch:param name="attribute" value="@uri" />
    </sch:pattern>    
    
    <sch:pattern is-a="requiredAttribute">
        <sch:param name="context" value="ns" />
        <sch:param name="attribute" value="@prefix" />
    </sch:pattern>                
    
</sch:schema>