多手机号XSD校验咨询:正则模式有效性与空值兼容方案
手机号XSD校验问题解答
场景与问题
示例XML
<ConsumerPhonenumbers> <ConsumerPhonenumber>0612345678</ConsumerPhonenumber> <ConsumerPhonenumber>+312012345678</ConsumerPhonenumber> </ConsumerPhonenumbers>
需求说明
手机号支持以下格式:+310612345678、310612345678、31612345678、0612345678、06.12345678、06-12345678,数字总长度需为10-12位,同时允许空的ConsumerPhonenumber节点。
当前XSD配置
<xs:element name="ConsumerPhonenumber" minOccurs="0" maxOccurs="5" nillable="false"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="\+?\d[\d -]{8,12}\d"></xs:pattern> </xs:restriction> </xs:simpleType> </xs:element>
遇到的问题:提交空的ConsumerPhonenumber时校验失败,同时不确定现有pattern规则是否正确。
问题1:现有pattern规则是否正确?
当前的pattern存在两个明显问题:
- 未覆盖分隔符需求:规则里只包含了数字、空格和
-,没有包含.,无法匹配06.12345678这类格式。 - 长度控制错误:
[\d -]{8,12}表示中间有8-12个字符,加上前后的\d,总长度会达到10-14位,超出了需求的10-12位数字总长度限制。
修正后的pattern
要覆盖所有允许的格式,同时保证数字总长度为10-12位,推荐使用以下pattern:
\+?(?:\d(?:[.-]?\d){9,11})
这个规则的逻辑:
\+?:允许开头有可选的+号(?:\d(?:[.-]?\d){9,11}):匹配10-12位数字,数字之间可以插入可选的.或-分隔符
如果不需要允许空格(需求里没提到空格格式),建议去掉原规则中的空格,避免匹配不符合要求的带空格手机号。
问题2:如何配置XSD接受空的ConsumerPhonenumber?
要允许空字符串内容,有两种可行方案:
方案1:修改pattern,加入空字符串匹配
在原有pattern前添加^$|,表示要么是空字符串,要么符合手机号格式:
<xs:element name="ConsumerPhonenumber" minOccurs="0" maxOccurs="5" nillable="false"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="^$|\+?(?:\d(?:[.-]?\d){9,11})"></xs:pattern> </xs:restriction> </xs:simpleType> </xs:element>
方案2:使用xs:union合并类型
定义一个联合类型,同时包含空字符串类型和手机号格式类型,逻辑更清晰:
<xs:element name="ConsumerPhonenumber" minOccurs="0" maxOccurs="5" nillable="false"> <xs:simpleType> <xs:union> <!-- 匹配空字符串 --> <xs:simpleType> <xs:restriction base="xs:string"> <xs:length value="0"/> </xs:restriction> </xs:simpleType> <!-- 匹配符合要求的手机号 --> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="\+?(?:\d(?:[.-]?\d){9,11})"></xs:pattern> </xs:restriction> </xs:simpleType> </xs:union> </xs:simpleType> </xs:element>
注意:保持nillable="false"是正确的,因为我们要允许的是空内容的节点,而不是带nil="true"属性的节点。
内容的提问来源于stack exchange,提问作者user20469827
相关产品推荐
相关产品推荐

