Search code examples
regexxmlxsdxsd-validationxml-validation

Need regex for restricted numbers in XSD


I am using below regex in WSDL for restrictions

<xsd:simpleType name="cfNumberType">
     <xsd:restriction base="xsd:string">
        <xsd:pattern value="((?=(^\d{3,9}$)|(^[0]\d{9}$))(?=^(?!11)\d+))" />
     </xsd:restriction>
</xsd:simpleType>

But its not working and giving error as

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Body>
      <SOAP-ENV:Fault>
         <faultcode>402</faultcode>
         <faultstring>Body: wrong format of input: failed to compile: xmlFAParseAtom: expecting ')' , failed to compile: xmlFAParseAtom: expecting ')' , failed to compile: xmlFAParseRegExp: extra characters , Element '{http://www.w3.org/2001/XMLSchema}pattern': The value '((?=(\d{3,9})|([0]\d{9}))(?=^(?!11)\d+))' of the facet 'pattern' is not a valid regular expression.</faultstring>
      </SOAP-ENV:Fault>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

But it's working as expected from PHP. What changes are needed in this expression so that it will work? It seems problem is with ^ and $ character as these are not accepted in XSD.

Logic of this regular expression is as below:

It should allow numbers from 3 up to 10 digits (excluding numbers starting with 11). When it's 10 digits, it should start with 0.


Solution

  • This definition of cfNumberType

      <xs:simpleType name="cfNumberType">
        <xs:restriction base="xs:string">
          <xs:pattern value="[023456789]\d{2,8}" />
          <xs:pattern value="\d[023456789]\d{1,7}" />
          <xs:pattern value="0\d{2,9}" />
        </xs:restriction>
      </xs:simpleType>
    

    consists of three xs:patterns which will respectively allow:

    • 3 to 9 digits without 1 in first place
    • 3 to 9 digits without 1 in second place
    • 10 digits with 0 in first place

    which is equivalent to your required logic.

    Test XSD

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="r">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="n" maxOccurs="unbounded" type="cfNumberType"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
      <xs:simpleType name="cfNumberType">
        <xs:restriction base="xs:string">
          <xs:pattern value="[023456789]\d{2,8}" />
          <xs:pattern value="\d[023456789]\d{1,7}" />
          <xs:pattern value="0\d{2,9}" />
        </xs:restriction>
      </xs:simpleType>
    </xs:schema>
    

    Test XML

    <?xml version="1.0" encoding="UTF-8"?>
    <r>
      <!-- valid -->
      <n>123</n>
      <n>1234</n>
      <n>12345</n>
      <n>123456</n>
      <n>1234567</n>
      <n>12345678</n>
      <n>0123456789</n>
      <!-- invalid -->
      <n/>
      <n>0</n>
      <n>01</n>
      <n>111</n>
      <n>1234567890</n>
      <n>12345678901</n>
    </r>