Skip to content

Instantly share code, notes, and snippets.

@djbpitt
Created November 4, 2021 15:25
Show Gist options
  • Save djbpitt/0894f05f6b2d25d4fbbc0751a00c1ad5 to your computer and use it in GitHub Desktop.
Save djbpitt/0894f05f6b2d25d4fbbc0751a00c1ad5 to your computer and use it in GitHub Desktop.
Schematron validation for order of tokens in attribute value
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2"
xmlns:sqf="http://www.schematron-quickfix.com/validator/process">
<sch:pattern>
<sch:p>Validates the insult types specified in the @type attribute on an &lt;insultStart&gt;
element. The value of @types must be a whitespace-separated token list consisting only
of one or more string tokens ordered as in $types with no other values and no
repetition.</sch:p>
<sch:p>If there are illegal values and the legal values are also in the wrong order, only
the illegal value error is reported. When that has been corrected, revalidation will
report the invalid order.</sch:p>
<sch:p>$allTypes is a sequence of all legal string values in the required order</sch:p>
<sch:let name="allTypes" value="'pAttack', 'slander', 'nameCall', 'sexGen', 'backComp'"/>
<sch:rule context="@type">
<sch:let name="myTypes" value="tokenize(.)"/>
<sch:let name="illegalValues" value="$myTypes[not(. = $allTypes)]"/>
<sch:assert test="empty($illegalValues)">"<sch:value-of select="$illegalValues"/>" not
permitted.</sch:assert>
<sch:report
test="empty($illegalValues) and not(deep-equal($allTypes[. = $myTypes], $myTypes))"
>The values "<sch:value-of select="$myTypes"/>" are legal but not in the correct
order.</sch:report>
</sch:rule>
</sch:pattern>
</sch:schema>
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="insult-test.sch" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<items>
<!-- -->
<!-- @type attribute value is a token string drawn from the following list:
pAttack, slander, nameCall, sexGen, backComp
@type values must appear in the order above
-->
<insultStart type="pAttack nameCall sexGen">valid</insultStart>
<insultStart type="nameCall pAttack sexGen">invalid: wrong order</insultStart>
<insultStart type="nameCall badValue sexGen">invalid: invalid token</insultStart>
<insultStart type="nameCall badValue1 sexGen badValue2">invalid: multiple invalid
tokens</insultStart>
<insultStart type="pAttack sexGen badValue nameCall">invalid: invalid token and valid tokens are
in wrong order</insultStart>
</items>
@djbpitt
Copy link
Author

djbpitt commented Nov 4, 2021

An <insultStart> element has a type attribute, the value of which is a whitespace-separated token string. The tokens are taken from a predefined list, and those that appear must appear in the predefined order. The two Schematron tests validate that:

  1. All tokens are legal values and
  2. If all tokens are legal values, they appear in the required order

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment