<?xml version="1.0" encoding="UTF-8"?>
<!--
  Schematron file for validating ISO/IEC 24752 conformant Socket Description files.

  @author Gottfried Zimmermann, ATG
  @version 2008-07-18
-->

<schema xmlns="http://purl.oclc.org/dsdl/schematron" xml:lang="en">
     <title>User Interface Socket Description (ISO/IEC 24752-2)</title>
     <ns prefix="uis" uri="http://myurc.org/ns/uisocketdesc"/>
     <ns prefix="xsd" uri="http://www.w3.org/2001/XMLSchema"/>
     <ns prefix="dc" uri="http://purl.org/dc/elements/1.1/"/>
     <ns prefix="dcterms" uri="http://purl.org/dc/terms/"/>

     <!--
  <pattern>
       <title> text </title>
     <rule context="">
     	<report test="">
### Error nnn: text
     	</report>
     </rule>
  </pattern>
-->

     <pattern>
          <title> 011 - dcterms:conformsTo </title>
          <rule context="/uis:uiSocket">
               <report test="count(dcterms:conformsTo) &gt; 1"> ### Error 011: Multiple
                    uis:uiSocket.dcterms:conformsTo elements. </report>
               <report test="count(dcterms:conformsTo) = 0"> ### Error 011: Missing
                    uis:uiSocket.dcterms:conformsTo element. </report>
               <report
                    test="(count(dcterms:conformsTo) = 1)
     		and (dcterms:conformsTo != 'http://myurc.org/iso24752-2/2007')"
                    > ### Error 011: uis:uiSocket.dcterms:conformsTo element must have content
                    http://myurc.org/iso24752-2/2007. </report>
          </rule>
     </pattern>

     <pattern>
          <title> 042 - Optional variable@timeout attribute of type xsd:boolean, but only if
               type=xsd:duration. </title>
          <rule context="uis:variable">
               <!-- Cannot check namespace of type, only checking local name -->
               <report test="(@timeout='true') and (substring-after(@type, ':')!='duration')"> ###
                    Error 042: The timeout variable with id '<value-of select="current()/@id"/>'
                    must have type xsd:duration. </report>
          </rule>
     </pattern>

     <pattern>
          <title> 057 - variable.dependency.insert element only allowed if attribute dim present,
               and final=false or not present. </title>
          <rule context="uis:variable">
               <assert
                    test="not(uis:dependency/uis:insert) or
     		(uis:dependency/uis:insert and @dim and (not(@final) or @final='false'))"
                    > ### Error 057: variable with id '<value-of select="current()/@id"/>' has an
                    insert dependency. This is only allowed for dimensional variables that are not
                    final. </assert>
          </rule>
     </pattern>

     <!-- Commented out since this has been corrected in errata version.
  <pattern><title> 099 - variable.selection.selectionSetDynamic@varRef </title> 
     <rule context="uis:variable/uis:selection/uis:selectionSetDynamic">
     	<let name="var" value="//uis:variable[@id=current()/@varRef]" />
     	<assert test="count($var)=1 and 
     	(substring-after($var/@type, ':')='stringList' or 
     		substring-after($var/@type, ':')='csvlist')">
### Error 099: variable.selection.selectionSetDynamic@varRef shall contain the id of a variable of type uis:stringList or uis:csvlist. Either there is no variable with id '<value-of select="current()/@varRef" />' or it has a wrong type.
     	</assert>
     </rule>
  </pattern>
-->

     <pattern>
          <title> 103 - A constant shall not occur within a dimensional set </title>
          <rule context="uis:constant">
               <report test="ancestor::uis:set[@dim]"> ### Error 103: The constant with id
                         '<value-of select="current()/@id"/>' has a dimensional set as ancestor.
               </report>
          </rule>
     </pattern>

     <pattern>
          <title> 113 - A constant element shall include a value which is specified as its element
               content. </title>
          <rule context="uis:constant">
               <!-- Somehow there can be multiple text content nodes.  Check the first one. -->
               <assert test="string-length(normalize-space(text()[position()=1])) &gt; 0"> ###
                    Error 103: The constant with id '<value-of select="current()/@id"/>' has no
                    element content." /> </assert>
          </rule>
     </pattern>

     <pattern>
          <title> 117 - command@type attribute must be empty or have one of the following values:
               uis:voidCommand, uis:basicCommand, uis:timedCommand. </title>
          <rule context="uis:command">
               <let name="typeLocalName" value="substring-after(@type, ':')"/>
               <!-- Cannot check type for correct namespace, only local name -->
               <assert
                    test="not(@type) or
     		@type='voidCommand' or $typeLocalName='voidCommand' or
     		@type='basicCommand' or $typeLocalName='basicCommand' or
     		@type='timedCommand' or $typeLocalName='timedCommand'"
                    > ### Error 117: command with id '<value-of select="current()/@id"/>' has no
                    valid type. </assert>
          </rule>
     </pattern>

     <pattern>
          <title> 118 - A command of type uis:voidCommand shall not have output or input-output
               parameters. </title>
          <rule context="uis:command">
               <let name="typeLocalName" value="substring-after(@type, ':')"/>
               <!-- Cannot check type for correct namespace, only local name -->
               <report
                    test="(not(@type) or @type='voidCommand' or $typeLocalName='voidCommand') and
     		(uis:param[@dir='out'] or uis:param[@dir='inout'])"
                    > ### Error 118: command with id '<value-of select="current()/@id"/>' is of type
                    uis:voidCommand and must not have input or input-output parameters. </report>
          </rule>
     </pattern>

     <pattern>
          <title> 127 - command@includesRes only if command is of type uis:basicCommand or
               uis:timedCommand. </title>
          <rule context="uis:command">
               <let name="typeLocalName" value="substring-after(@type, ':')"/>
               <!-- Cannot check type for correct namespace, only local name -->
               <report
                    test="@includesRes and
     		(not(@type) or @type='voidCommand' or $typeLocalName='voidCommand')"
                    > ### Error 127: command with id '<value-of select="current()/@id"/>' has
                    dynamic resources, but is of type uis:voidCommand. </report>
          </rule>
     </pattern>

     <pattern>
          <title> 136 - command.dependency.insert element only if command has dim attribute. </title>
          <rule context="uis:command">
               <report test="uis:dependency/uis:insert and not(@dim)"> ### Error 136: command with
                    id '<value-of select="current()/@id"/>' has an insert dependency. This is only
                    allowed for dimensional commands. </report>
          </rule>
     </pattern>

     <pattern>
          <title> 145 - Either command.param@id or command.param@idref attribute. </title>
          <rule context="uis:command/uis:param">
               <assert test="@id or @idref"> ### Error 145: command with id '<value-of
                         select="../@id"/>' has a parameter with neither @id nor @idref. </assert>
          </rule>
     </pattern>

     <pattern>
          <title> 147 - command.param@idref must reference the id attribute of a variable or set in
               the same socket. </title>
          <rule context="uis:command/uis:param/@idref">
               <assert test="//uis:variable[@id=current()] or //uis:set[@id=current()]"> ### Error
                    147: global command parameter with invalid idref '<value-of select="current()"
                    />'. </assert>
          </rule>
     </pattern>

     <pattern>
          <title> 151 - A local parameter shall have a 'type' attribute. </title>
          <rule context="uis:command/uis:param/@id">
               <assert test="../@type"> ### Error 151: local command parameter with id '<value-of
                         select="current()"/>' must have a type attribute. </assert>
          </rule>
     </pattern>

     <pattern>
          <title> 152 - A global parameter shall not have a 'type' attribute. </title>
          <rule context="uis:command/uis:param/@idref">
               <assert test="not(../@type)"> ### Error 152: global command parameter with idref
                         '<value-of select="current()"/>' must not have a type attribute. </assert>
          </rule>
     </pattern>

     <pattern>
          <title> 155 - A global parameter shall not have a 'secret' attribute. </title>
          <rule context="uis:command/uis:param/@idref">
               <assert test="not(../@secret)"> ### Error 155: global command parameter with idref
                         '<value-of select="current()"/>' must not have a secret attribute.
               </assert>
          </rule>
     </pattern>

     <pattern>
          <title> 158 - A global parameter shall not have a 'sensitive' attribute. </title>
          <rule context="uis:command/uis:param/@idref">
               <assert test="not(../@sensitive)"> ### Error 158: global command parameter with idref
                         '<value-of select="current()"/>' must not have a sensitive attribute.
               </assert>
          </rule>
     </pattern>

     <pattern>
          <title> 173 - notify.dependency.insert element only if notify has dim attribute. </title>
          <rule context="uis:notify">
               <report test="uis:dependency/uis:insert and not(@dim)"> ### Error 136: notify element
                    with id '<value-of select="current()/@id"/>' has an insert dependency, but no
                    dim attribute. </report>
          </rule>
     </pattern>

     <pattern>
          <title> 186 - No multiple xsd:schema elements </title>
          <rule context="/uis:uiSocket">
               <report test="count(xsd:schema) &gt; 1"> ### Error 186: Multiple xsd:schema
                    elements. </report>
          </rule>
     </pattern>

     <pattern>
          <title> 187 - xsd:schema subelements </title>
          <rule context="/uis:uiSocket/xsd:schema">
               <assert test="count(xsd:complexType) + count(xsd:simpleType) = count(*)"> ### Error
                    187: Inside xsd:schema, only xsd:complexType elements or xsd:simpleType elements
                    are allowed. </assert>
          </rule>
     </pattern>

     <pattern>
          <title> 188 - xsd:schema without @targetNamespace </title>
          <rule context="/uis:uiSocket/xsd:schema">
               <report test="@targetNamespace or @xsd:targetNamespace"> ### Error 188: xsd:schema
                    must not have a targetNamespace attribute. </report>
          </rule>
     </pattern>

     <pattern>
          <title> 189 - xsd:simpleType or xsd:complexType must have @id </title>
          <rule context="/uis:uiSocket/xsd:schema//xsd:simpleType">
               <assert test="@id"> ### Error 188: xsd:simpleType must have an id attribute.
               </assert>
          </rule>
          <rule context="/uis:uiSocket/xsd:schema//xsd:complexType">
               <assert test="@id"> ### Error 189: xsd:complexType must have an id attribute.
               </assert>
          </rule>
     </pattern>

     <pattern>
          <title> 190 - xsd:restriction allowed facets </title>
          <rule context="/uis:uiSocket/xsd:schema//xsd:restriction">
               <report test="xsd:totalDigits or xsd:fractionDigits"> ### Error 190: The constraining
                    facets xsd:totalDigits and xsd:fractionDigits must not be used. </report>
          </rule>
     </pattern>

</schema>
