
Hugh -- Are you still working on this? And it's in branch hcayless-appcrit, not branch appcrit, right? (Can we somehow sequester whichever one is *not* current? It's confusing.) I haven't looked through all the rules carefully (but hope to be able to do so tomorrow). But I did notice at least one problem. Everywhere you have not( parent::tei:note ) it should probably be not( ancestor::tei:note ) lest, e.g., the <lg> in the structure <p>This is a dangling paragraph describing superficial sights. <note> <p>An blatant reference to <title>The Dangling Conversation</title>, a Simon and Garfunkel song: <quote> <lg type="verse"> <l>In the dangling conversation</l> <l>And the superficial sighs</l> <l>The borders of our lives</l> </lg> </quote> </p> </note> be flagged by "abstractModel-structure-l" as violating the abstract model. Overall, the current piecemeal approach is problematic, I think. My instinct is we would do better to have all of these <constraint>s in the same place, both in the source (e.g., all in the app.xml file) and in the execution (e.g., all rules have a context of tei:app). So something like the following (which is without thinking things through or testing them :-) <sch:rule context="tei:app"> <sch:report test=" ( ancestor::tei:p[not( ancestor::tei:note ) ] or ancestor::tei:ab[not( ancestor::tei:note ) ] ) and ( descendant::tei:p[not( ancestor::tei:note ) ] or descendant::tei:ab[not( ancestor::tei:note ) ] ) ">An 'app' that is inside a 'p' or 'ab' can not have a 'p' or 'ab' inside it</sch:report> </sch:rule> This has the advantage of being *much* easier to maintain (although not as easy as automagically-generated-at-build-time :-), and that we won't have Schematron rules firing for every <p> and <l>, only for <app>s. It has the disadvantage that the user does not get told precisely which <p> or <ab> is the problem. (But then again, with the current approach the user is only told about 1/2 the problem.)