XML XSD验证问题:国家与对应州枚举校验报错求助
问题:XSD 1.1 xs:alternative 验证报错
我是XML XSD验证新手,想把XML里的国家做成枚举校验,同时校验每个国家对应的州。用XSD 1.1的xs:alternative关联国家和州的枚举类型,但验证器报错:"A Problem Was Found Starting At: Alternative",求解决。
我的XML代码
<?xml version="1.0" encoding="UTF-8"?> <mylist xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test.xsd"> <myrow> <country>Country 1</country> <state>State 11</state> </myrow> <myrow> <country>Country 2</country> <state>State 22</state> </myrow> <myrow> <country>Country 3</country> <state>State 33</state> </myrow> </mylist>
我的XSD代码
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1"> <xs:element name="mylist"> <xs:complexType> <xs:sequence> <xs:element name="myrow" maxOccurs="unbounded" minOccurs="0"> <xs:complexType> <xs:sequence> <xs:element name="country" type="country_type" /> <xs:element name="state" > <xs:alternative test="$country eq 'Country 1'" type="country_1_states_type"/> <xs:alternative test="$country eq 'Country 2'" type="country_2_states_type"/> <xs:alternative test="$country eq 'Country 3'" type="country_3_states_type"/> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <!-- LookUp Lists --> <xs:simpleType name="country_type"> <xs:restriction base="xs:string"> <xs:enumeration value="Country 1"/> <xs:enumeration value="Country 2"/> <xs:enumeration value="Country 3"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="country_1_states_type"> <xs:restriction base="xs:string"> <xs:enumeration value="State 11"/> <xs:enumeration value="State 12"/> <xs:enumeration value="State 13"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="country_2_states_type"> <xs:restriction base="xs:string"> <xs:enumeration value="State 21"/> <xs:enumeration value="State 22"/> <xs:enumeration value="State 23"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="country_3_states_type"> <xs:restriction base="xs:string"> <xs:enumeration value="State 31"/> <xs:enumeration value="State 32"/> <xs:enumeration value="State 33"/> </xs:restriction> </xs:simpleType> </xs:schema>
解决方案
报错核心原因是:xs:alternative不能直接嵌套在<xs:element>的内部类型定义中,它的正确使用场景是在元素或复杂类型层面做类型切换。同时原代码中XPath变量引用的上下文逻辑也存在问题。
修改后的XSD代码如下:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1"> <!-- 为每个国家定义对应的myrow复杂类型 --> <xs:complexType name="country1RowType"> <xs:sequence> <xs:element name="country" type="xs:string" fixed="Country 1"/> <xs:element name="state" type="country_1_states_type"/> </xs:sequence> </xs:complexType> <xs:complexType name="country2RowType"> <xs:sequence> <xs:element name="country" type="xs:string" fixed="Country 2"/> <xs:element name="state" type="country_2_states_type"/> </xs:sequence> </xs:complexType> <xs:complexType name="country3RowType"> <xs:sequence> <xs:element name="country" type="xs:string" fixed="Country 3"/> <xs:element name="state" type="country_3_states_type"/> </xs:sequence> </xs:complexType> <!-- 主元素定义 --> <xs:element name="mylist"> <xs:complexType> <xs:sequence> <xs:element name="myrow" maxOccurs="unbounded" minOccurs="0"> <!-- 在myrow元素层面使用xs:alternative切换类型 --> <xs:alternative test="country eq 'Country 1'" type="country1RowType"/> <xs:alternative test="country eq 'Country 2'" type="country2RowType"/> <xs:alternative test="country eq 'Country 3'" type="country3RowType"/> <!-- 可选默认类型,处理无匹配的异常情况 --> <xs:alternative type="xs:anyType"/> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <!-- 枚举类型定义保持不变 --> <xs:simpleType name="country_1_states_type"> <xs:restriction base="xs:string"> <xs:enumeration value="State 11"/> <xs:enumeration value="State 12"/> <xs:enumeration value="State 13"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="country_2_states_type"> <xs:restriction base="xs:string"> <xs:enumeration value="State 21"/> <xs:enumeration value="State 22"/> <xs:enumeration value="State 23"/> </xs:restriction> </xs:simpleType> <xs:simpleType name="country_3_states_type"> <xs:restriction base="xs:string"> <xs:enumeration value="State 31"/> <xs:enumeration value="State 32"/> <xs:enumeration value="State 33"/> </xs:restriction> </xs:simpleType> </xs:schema>
关键修改说明
- 调整
xs:alternative的位置:将其从state元素内部移到myrow元素层面,符合XSD 1.1的语法规则。 - 绑定国家与州的对应关系:为每个国家单独定义
myrow复杂类型,固定country值并绑定对应的state枚举,确保校验逻辑严谨。 - 简化XPath表达式:直接使用
country eq 'XXX',上下文为当前myrow元素,无需变量引用。 - 兼容验证器要求:确保使用支持XSD 1.1的验证工具(如Saxon-HE 9.5+、XMLSpy等),旧工具仅支持XSD 1.0会导致报错。
内容的提问来源于stack exchange,提问作者Deepak
相关产品推荐
相关产品推荐

