Re: [Schematron-love-in] Is it possible to write a schematron rule which validate the number of occurence of a list ?

Hi Anne,

> I'm wondering if it is possible to write a schematron rule which
> validate the number of occurence of a list ?

<snip/>

> I would like to add to this schema a rule which verify that length of
> the list must be equal to the value of the Number attribut.
> So such Xml document will be valid :
>
> <?xml version="1.0" ?>
> <ROOT xmlns:sdf="http://www.w3.org/2001/XMLSchema-instance"
> sdf:noNamespaceSchemaLocation="test.xsd">
>  <LIST Number='2'>Hello Bonjour</LIST>
> </ROOT>
>
> And this one not :
>
> <?xml version="1.0" ?>
> <ROOT xmlns:sdf="http://www.w3.org/2001/XMLSchema-instance"
> sdf:noNamespaceSchemaLocation="test.xsd">
>  <LIST Number='1'>Hello Bonjour</LIST>
> </ROOT>
>
> Is there a way to do that ?

Yes, you can do this with an embedded Schematron rule. It's a bit tricky since
Schematron only have access to the functions in XSLT and XPath but here's how it
can be done.
Since list types in XML Schema are separated by space characters we know that the
number of items in the list must be equal to number of spaces + 1. Since we know
this we can use the string-length() function in XPath to check the constraint:

NoTotChar = The total number of characters for the LIST value =
string-length(text())
NoCharNoSpace = The total number of characters for the LIST value without spaces =
string-length(translate(text(), ' ', ''))
NoSpaces = The total number of spaces in the LIST value = NoTotChar -
NoCharNoSpace
NoListItems = NoSpaces + 1

There's all the information we need so add the following Schematron rule to the
LIST element declaration:

       <pattern name="Check list length"
xmlns="http://www.ascc.net/xml/schematron">
        <rule context="ROOT/LIST">
         <assert diagnostics="d1" test="(string-length(text()) -
string-length(translate(text(), ' ', ''))) + 1 = @Number">The number of items in
the list doesn't match the value of the Number attribute.</assert>
        </rule>
       </pattern>

The complete schema can be found below.

Cheers,
/Eddie

-------------------------------------8<-------------------------------------------

<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <!-- Definition of the List Type -->
 <xsd:simpleType name="ListType">
  <xsd:list itemType="xsd:string"/>
 </xsd:simpleType>

 <xsd:element name="ROOT">
  <xsd:complexType>
   <xsd:sequence>
    <!-- List -->
    <xsd:element name="LIST">
     <xsd:annotation>
      <xsd:appinfo>
       <pattern name="Check list length"
xmlns="http://www.ascc.net/xml/schematron">
        <rule context="ROOT/LIST">
         <assert diagnostics="d1" test="(string-length(text()) -
string-length(translate(text(), ' ', ''))) + 1 = @Number">The number of items in
the list doesn't match the value of the Number attribute.</assert>
        </rule>
       </pattern>
      </xsd:appinfo>
     </xsd:annotation>
     <xsd:complexType>
      <xsd:simpleContent>
       <xsd:extension base="ListType">
        <xsd:attribute name="Number" type="xsd:integer" use="required"/>
       </xsd:extension>
      </xsd:simpleContent>
     </xsd:complexType>
    </xsd:element>
   </xsd:sequence>
  </xsd:complexType>
 </xsd:element>
</xsd:schema>

Received on Thursday, 11 April 2002 01:05:12 UTC