Search code examples
xsltxpathschematron

SchemaTron check preceding attributes


  <ROOTNODE>
   <Blocks>
     <Block>
    <Ref/>
      <BlockDates Start="2015-10-20" End="2015-10-20" />
      <Types>
        <Type TypeCode="SGL" />
      </Types>
    </Block>

    <Block>
      <Ref/>
      <BlockDates Start="2015-10-19" End="2015-10-18"/>
      <Types>
        <Type TypeCode="SGL" />
       </Types>
    </Block>
   </Blocks>
   </ROOTNODE>

I need to report an error if the @Start date is less than the preceding @End date. But only if the @TypeCode is the same as the preceding @TypeCode. The above should generate an error. Below is what I have tried. Any help is appreciated!

   <sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron">
                <sch:pattern>
                    <sch:rule context="BlockDates|Type">
                            <sch:report test="translate(@Start, '-', '') &lt;= translate(preceding::*/@End, '-', '') and @TypeCode = preceding::*/@TypeCode"> Error start date is before end date and type codes match.     </sch:report>                                                               
    </sch:rule>                                    </sch:pattern>                                                              
    </sch:schema>

Solution

  • I would use the Block element as the context:

    <sch:pattern>
        <sch:rule context="Block[Types/Type/@TypeCode = preceding-sibling::Block[1]/Types/Type/@TypeCode]">
            <sch:assert test="translate(BlockDates/@Start, '-', '') &lt; translate(preceding-sibling::Block[1]/@End, '-', '')"></sch:assert>
        </sch:rule>
    </sch:pattern>