<!-- ==========================================================-->

<annex normative="false"  id="svrl">
<title>Schematron Validation Report Language</title>
<clause>
<title>Description</title>
<p>The Schematron Validation Report Language (SVRL) is
a simple XML language which may be used for reporting the
results of Schematron validation and for conformance
suites. 
</p>
<p>The order of elements in an SVRL is implementation-dependent;
different implementations may generate the same elements in
a different order.</p>
</clause>
<clause>
<title>DTD</title>
<pre xml:space="preserve" ><![CDATA[<!--
       (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.
 -->

<!ELEMENT schematron-output  
    (text*, ns*, (active-pattern, 
        (fired-rule, (failed-assert|successful-report)*)+)+)>
   
<!-- only active patterns are reported -->
<!ELEMENT active-pattern  EMPTY>

<!-- only references are reported, not the diagnostic -->
<!ELEMENT diagnostic-reference (#PCDATA)  >

<!-- only failed assertions are reported -->
<!ELEMENT failed-assert  ( diagnostic-reference*, text )>

<!-- only rules that are fired are reported, abstract/extend handling
         should have been done before -->
<!ELEMENT fired-rule EMPTY >

<!-- only namespaces from sch:ns need to be reported -->
<!ELEMENT ns EMPTY >

<!-- only successful asserts are reported -->
<!ELEMENT successful-report (  diagnostic-reference*, text ) >

<!ELEMENT text (#PCDATA )>

<!ATTLIST schematron-output
    title CDATA #IMPLIED
    phase NMTOKEN #IMPLIED
    schemaVersion CDATA #IMPLIED 
    xmlns CDATA "http://purl.oclc.org/dsdl/svrl" >

<!ATTLIST active-pattern
    id ID #IMPLIED
    name CDATA #IMPLIED 
    role NMTOKEN #IMPLIED >

<!ATTLIST diagnostic-reference
    diagnostic NMTOKEN #REQUIRED >

<!ATTLIST failed-assert
    id ID #IMPLIED
    location CDATA #REQUIRED
    test CDATA #REQUIRED 
    role NMTOKEN #IMPLIED 
    flag NMTOKEN #IMPLIED >         

<!ATTLIST fired-rule
    id ID #IMPLIED
    context CDATA #REQUIRED 
    role NMTOKEN #IMPLIED 
    flag NMTOKEN #IMPLIED >         
   
<!ATTLIST ns
    prefix NMTOKEN #REQUIRED
    uri  CDATA #REQUIRED >          

<!ATTLIST successful-report
    id ID #IMPLIED
    location CDATA #REQUIRED
    test  CDATA #REQUIRED
    role NMTOKEN #IMPLIED 
    flag NMTOKEN #IMPLIED > ]]>
</pre>
</clause>
<clause>
<title>Schematron Schema</title>
<p>The corresponding Schematron schema is:</p>
<pre xml:space="preserve"><![CDATA[<!--
       (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:ns prefix="svrl" uri="http://purl.oclc.org/dsdl/svrl" />    
    
    <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="../svrl: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="svrl:schematron-output">
            <sch:assert test="not(../*)">
                The <sch:name/> element is the root element.
            </sch:assert>
            <sch:assert 
                test="count(svrl:text) + count(svrl:ns) + count(svrl:active-pattern) +
                    count(svrl:fired-rule) + count(svrl:failed-assert) +
                    count(svrl: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="svrl:active-pattern">
                <sch:name/> should have at least one active pattern.
            </sch:assert>
        </sch:rule>
        
        <sch:rule context="svrl:text">
            <sch:extends rule="childless" />
        </sch:rule>
        
        <sch:rule context="svrl: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="svrl:ns">
            <sch:extends rule="second-level" />
            <sch:extends rule="empty" />
            <sch:assert 
                test="following-sibling::svrl:active-pattern 
                      or following-sibling::svrl:ns"> 
                A <sch:name/> comes before an active-pattern or another 
                ns element.
            </sch:assert>
        </sch:rule>
        
        <sch:rule context="svrl:active-pattern">
            <sch:extends rule="second-level" />
            <sch:extends rule="empty" />
        </sch:rule>
        
        <sch:rule context="svrl:fired-rule">
            <sch:extends rule="second-level" />
            <sch:extends rule="empty" />
            <sch:assert 
                test="preceding-sibling::active-pattern |
                    preceding-sibling::svrl:fired-rule |
                    preceding-sibling::svrl:failed-assert |
                    preceding-sibling::svrl: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="svrl:failed-assert | svrl:successful-report">
            <sch:extends rule="second-level" />
            <sch:assert 
                test="count(svrl:diagnostic-reference) + count(svrl:text) = count(*)"> 
                The <sch:name/> element should only contain a text element 
                and diagnostic reference elements.
            </sch:assert>
            <sch:assert test="count(svrl:text) = 1"> 
                The <sch:name/> element should only contain a text element.
            </sch:assert>
            <sch:assert test="preceding-sibling::svrl:fired-rule |
                preceding-sibling::svrl:failed-assert |
                preceding-sibling::svrl: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="svrl:diagnostic-reference" />
        <sch:param name="attribute" value="@diagnostic" />
    </sch:pattern>    
    
    <sch:pattern is-a="requiredAttribute">
        <sch:param name="context" value="svrl:failed-assert or svrl:successful-report" />
        <sch:param name="attribute" value="@location" />
    </sch:pattern>    
    
    <sch:pattern is-a="requiredAttribute">
        <sch:param name="context" value="svrl:failed-assert or svrl:successful-report" />
        <sch:param name="attribute" value="@test" />
    </sch:pattern>    

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

</pre>
</clause>
</annex>
