<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<axsl:stylesheet xmlns:axsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:sch="http://www.ascc.net/xml/schematron" version="1.0">
  <axsl:output method="text"/>

  <axsl:template mode="schematron-get-full-path" match="*|@*">
    <axsl:apply-templates mode="schematron-get-full-path" select="parent::*"/>
    <axsl:text>/</axsl:text>
    <axsl:if test="count(. | ../@*) = count(../@*)">@</axsl:if>
    <axsl:value-of select="name()"/>
    <axsl:text>[</axsl:text>
    <axsl:value-of 
      select="1+count(preceding-sibling::*[name()=name(current())])"/>
    <axsl:text>]</axsl:text>
  </axsl:template>

  <axsl:template match="/">
    <axsl:apply-templates mode="M0" select="/"/>
  </axsl:template>

  <axsl:template mode="M0" priority="4000" match="/*">
    <axsl:choose>
      <axsl:when test="name() = 'sonnet'"/>
      <axsl:otherwise>
        In pattern name() = 'sonnet':
        Root element must be &lt;sonnet&gt;.
      </axsl:otherwise>
    </axsl:choose>
    <axsl:choose>
      <axsl:when test="@type = 'Shakespearean' or @type = 'Petrarchan'"/>
      <axsl:otherwise>
        In pattern @type = 'Shakespearean' or @type = 'Petrarchan':
        Valid values for the type attribute are "Shakespearean" or "Petrarchan."
      </axsl:otherwise>
    </axsl:choose>
    <axsl:choose>
      <axsl:when test="count(*) &lt; 4"/>
      <axsl:otherwise>
        In pattern count(*) &lt; 4:
        The &lt;sonnet&gt; element contains a &lt;author&gt; element, an optional 
        &lt;title&gt; element, and a &lt;lines&lt; element.
      </axsl:otherwise>
    </axsl:choose>
    <axsl:choose>
      <axsl:when test="*[1] = author"/>
      <axsl:otherwise>
        In pattern *[1] = author:
        The first child of the &lt;sonnet&gt; element must be an 
        &lt;author&gt; element.
      </axsl:otherwise>
    </axsl:choose>
    <axsl:choose>
      <axsl:when test="(count(*) = 2 and *[2] = lines) or 
                       (count(*) = 3 and *[2] = title and *[3] = lines)"/>
      <axsl:otherwise>
        In pattern (count(*) = 2 and *[2] = lines) or 
                   (count(*) = 3 and *[2] = title  and *[3] = lines):
        If you use the optional &lt;title&gt; element, the &lt;sonnet&gt; 
        element must contain the &lt;author&gt;, &lt;title&gt; and &lt;lines&gt; 
        elements in that order.
      </axsl:otherwise>
    </axsl:choose>
    <axsl:apply-templates mode="M0"/>
  </axsl:template>
  <axsl:template mode="M0" priority="3999" match="author">
    <axsl:choose>
      <axsl:when test="count(*) &lt; 6"/>
      <axsl:otherwise>
        In pattern count(*) &lt; 6:
        An &lt;author&gt; element must have the elements &lt;lastName&gt;, 
        &lt;firstName&gt;, &lt;nationality&gt; &lt;yearOfBirth&gt; and 
        &lt;yearOfDeath&gt;. (The &lt;yearOfBirth&gt; and &lt;yearOfDeath&gt; 
        elements are optional.
      </axsl:otherwise>
    </axsl:choose>
    <axsl:choose>
      <axsl:when test="*[1] = lastName"/>
      <axsl:otherwise>
        In pattern *[1] = lastName:
        The first child of the &lt;author&gt; element must be a 
        &lt;lastName&gt; element.
      </axsl:otherwise>
    </axsl:choose>
    <axsl:choose>
      <axsl:when test="*[2] = firstName"/>
      <axsl:otherwise>
        In pattern *[2] = firstName:
        The second child of the &lt;author&gt; element must be a 
        &lt;firstName&gt; element.
      </axsl:otherwise>
    </axsl:choose>
    <axsl:choose>
      <axsl:when test="*[3] = nationality"/>
      <axsl:otherwise>
        In pattern *[3] = nationality:
        The third child of the &lt;author&gt; element must be a 
        &lt;nationality&gt; element.
      </axsl:otherwise>
    </axsl:choose>
    <axsl:choose>
      <axsl:when test="(count(*) = 4 and *[4] = yearOfBirth) or
                       (count(*) = 5 and *[4] = yearOfBirth and 
                        *[5] = yearOfDeath)"/>
      <axsl:otherwise>
        In pattern (count(*) = 4 and *[4] = yearOfBirth) or (count(*) = 5 and 
                    *[4] = yearOfBirth and *[5] = yearOfDeath):
        The fourth child of the &lt;author&gt; element must be a 
        &lt;yearOfBirth&gt; element.
      </axsl:otherwise>
    </axsl:choose>
    <axsl:apply-templates mode="M0"/>
  </axsl:template>
  <axsl:template mode="M0" priority="3998" match="lines">
    <axsl:choose>
      <axsl:when test="count(line) = 14"/>
      <axsl:otherwise>
        In pattern count(line) = 14:
        A sonnet must have 14 &lt;line&gt;s.
      </axsl:otherwise>
    </axsl:choose>
    <axsl:choose>
      <axsl:when test="count(line) = count(*)"/>
      <axsl:otherwise>
        In pattern count(line) = count(*):
        The &lt;lines&gt; element can only contain &lt;line&gt; elements. 
      </axsl:otherwise>
    </axsl:choose>
    <axsl:apply-templates mode="M0"/>
  </axsl:template>
  <axsl:template mode="M0" priority="-1" match="text()"/>
  <axsl:template priority="-1" match="text()"/>
</axsl:stylesheet>

