XML Schema中同一元素名下简单与复杂类型的定义问题
解决XML Schema中ADDRESS元素多类型定义的问题
问题场景
现有如下XML文档,其中ADDRESS元素支持两种形式:一种是嵌套STREET和NUMBER子元素的复杂结构,另一种是直接存储字符串内容:
<CLIENTS> <CLIENT ID="18"> <NAME>Tim</NAME> <MIDDLE_NAME>Billy</MIDDLE_NAME> <SURNAME>Riggins</SURNAME> <ADDRESS> <STREET> Eight St </STREET> <NUMBER>3</NUMBER> </ADDRESS> <EMAIL>tim_riggins@fnl.com</EMAIL> <PHONE_NUMBER>756-2222</PHONE_NUMBER> </CLIENT> <CLIENT ID="19"> <BASIC_INFO> <NAME>James</NAME> <MIDDLE_NAME>Morgan</MIDDLE_NAME> <SURNAME>McGill</SURNAME> <ADDRESS>Ninth St.1</ADDRESS> </BASIC_INFO> <EMAIL>james_mcgill@bcs.com</EMAIL> <PHONE_NUMBER>756-3333</PHONE_NUMBER> </CLIENT> </CLIENTS>
最初编写的Schema尝试定义ADDRESS类型,但触发报错:Cvc-complex-type.2.4.b: The Content Of Element 'ADDRESS' Is Not Complete. One Of '{STREETSIMPLE, STREETCOMPLEX}' Is Expected。
错误原因
原Schema中定义的STREET-TYPE要求ADDRESS元素必须包含STREETSIMPLE或STREETCOMPLEX子元素,但实际XML里的ADDRESS要么直接是文本,要么直接嵌套STREET和NUMBER,完全不匹配这个结构,导致校验失败。
正确的Schema定义
需要直接为ADDRESS定义支持两种内容形式的类型,无需额外的中间元素。完整Schema如下:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <!-- 可选:约束地址字符串的格式 --> <xsd:simpleType name="AddressStringType"> <xsd:restriction base="xsd:string"> <xsd:pattern value="[A-Za-z]+( St\.?[0-9]{1,2})?"/> </xsd:restriction> </xsd:simpleType> <!-- 定义ADDRESS的核心类型:支持两种内容形式 --> <xsd:complexType name="AddressType"> <xsd:choice> <!-- 形式1:嵌套STREET和NUMBER子元素 --> <xsd:sequence> <xsd:element name="STREET" type="xsd:string"/> <xsd:element name="NUMBER" type="xsd:integer"/> </xsd:sequence> <!-- 形式2:直接文本内容 --> <xsd:simpleContent> <xsd:extension base="AddressStringType"/> </xsd:simpleContent> </xsd:choice> </xsd:complexType> <!-- 定义第一种CLIENT结构(无BASIC_INFO) --> <xsd:complexType name="ClientType"> <xsd:sequence> <xsd:element name="NAME" type="xsd:string"/> <xsd:element name="MIDDLE_NAME" type="xsd:string"/> <xsd:element name="SURNAME" type="xsd:string"/> <xsd:element name="ADDRESS" type="AddressType"/> <xsd:element name="EMAIL" type="xsd:string"/> <xsd:element name="PHONE_NUMBER" type="xsd:string"/> </xsd:sequence> <xsd:attribute name="ID" type="xsd:integer" use="required"/> </xsd:complexType> <!-- 定义BASIC_INFO结构 --> <xsd:complexType name="BasicInfoType"> <xsd:sequence> <xsd:element name="NAME" type="xsd:string"/> <xsd:element name="MIDDLE_NAME" type="xsd:string"/> <xsd:element name="SURNAME" type="xsd:string"/> <xsd:element name="ADDRESS" type="AddressType"/> </xsd:sequence> </xsd:complexType> <!-- 定义第二种CLIENT结构(包含BASIC_INFO) --> <xsd:complexType name="ClientWithBasicInfoType"> <xsd:sequence> <xsd:element name="BASIC_INFO" type="BasicInfoType"/> <xsd:element name="EMAIL" type="xsd:string"/> <xsd:element name="PHONE_NUMBER" type="xsd:string"/> </xsd:sequence> <xsd:attribute name="ID" type="xsd:integer" use="required"/> </xsd:complexType> <!-- 根元素CLIENTS --> <xsd:element name="CLIENTS"> <xsd:complexType> <xsd:choice maxOccurs="unbounded"> <xsd:element name="CLIENT" type="ClientType"/> <xsd:element name="CLIENT" type="ClientWithBasicInfoType"/> </xsd:choice> </xsd:complexType> </xsd:element> </xsd:schema>
关键说明
AddressType通过<xsd:choice>直接指定两种合法内容:要么是STREET+NUMBER的序列,要么是符合格式约束的文本内容。- 这样定义后,XML中的两种
ADDRESS写法都能通过Schema校验,解决了原报错问题。
内容的提问来源于stack exchange,提问作者Vladimir99
相关产品推荐
相关产品推荐

