XSD中受限制的数字需要正则表达式

时间:2016-09-09 08:45:11

标签: regex xml xsd xsd-validation xml-validation

我在WSDL中使用以下正则表达式进行限制

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

但是它不起作用并且给出错误

<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>

但是它的工作正如PHP预期的那样。 此表达式需要进行哪些更改才能使用?似乎问题在于^$字符,因为XSD中不接受这些字符。

这个正则表达式的逻辑如下:

它应该允许3到10位数字(不包括以11开头的数字)。当它是10位数时,它应该从0开始。

1 个答案:

答案 0 :(得分:1)

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>

由三个xs:patterns组成,分别允许:

  • 首先没有1的3到9位数字
  • 3到9位数,第二位没有1
  • 10位数,第一位为0

相当于您所需的逻辑。

测试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>

测试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>