基于EL0属性值约束EL2子元素的XSD编写求助
问题描述
我完全不会编写符合要求的XSD,需求如下:
XML示例
XML1
<EL0 attr0="type1"> <EL1 attr1="someValue"/> <EL2> <EL2_SUBEL1>String1</EL2_SUBEL1> <EL2_SUBEL2 attr2="value1"/> </EL2> </EL0>
XML2
<EL0 attr0="type2"> <EL1 attr1="someValue"/> <EL2> <EL2_SUBEL3>String1</EL2_SUBEL3> </EL2> <EL3 attr4="value2"/> </EL0>
元素规则
- 根元素:
EL0 - 根节点下可出现的元素(顺序任意):
EL1:必须带attr1属性EL2:子元素由EL0的attr0属性决定EL3:必须带attr4属性,仅EL0的attr0为type2时出现
EL2子元素规则:
可选子元素:
return (<EL2_SUBEL1>String1</EL2_SUBEL1> <EL2_SUBEL2 attr2="value1"/> )
return (<EL2_SUBEL3>String2</EL2_SUBEL3> ``` - 当`EL0`的`attr0`为`type1`时,`EL2`必须包含`EL2_SUBEL1`和`EL2_SUBEL2` - 当`EL0`的`attr0`为`type2`时,`EL2`必须包含`EL2_SUBEL3` 我写的XSD无法正常工作,代码如下,请求修正: ```xsd <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <!-- Define complex type for EL1 --> <xs:complexType name="EL1Type"> <xs:attribute name="id" type="xs:string"/> </xs:complexType> <!-- Define complex type for EL2_SUBEL1 --> <xs:complexType name="EL2_SUBEL1Type"> <xs:sequence> <xs:element name="EL2_SUBEL1" type="xs:string"/> </xs:sequence> </xs:complexType> <!-- Define complex type for EL2_SUBEL2 --> <xs:complexType name="EL2_SUBEL2Type"> <xs:sequence> <xs:element name="EL2_SUBEL2"> <xs:complexType> <xs:attribute name="value" type="xs:string"/> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> <!-- Define complex type for EL2_SUBEL3 --> <xs:complexType name="EL2_SUBEL3Type"> <xs:sequence> <xs:element name="EL2_SUBEL3" type="xs:string"/> </xs:sequence> </xs:complexType> <!-- Define complex type for EL3 --> <xs:complexType name="EL3Type"> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="number" type="xs:string"/> </xs:extension> </xs:simpleContent> </xs:complexType> <!-- Define complex type for EL3 for "type1" --> <xs:complexType name="type1"> <xs:sequence> <xs:element ref="EL2_SUBEL1" minOccurs="0" maxOccurs="1"/> <xs:element ref="EL2_SUBEL2" minOccurs="0" maxOccurs="1"/> </xs:sequence> </xs:complexType> <!-- Define complex type for EL3 for "type2" --> <xs:complexType name="type2"> <xs:sequence> <xs:element ref="EL2_SUBEL3" minOccurs="0" maxOccurs="1"/> </xs:sequence> </xs:complexType> <!-- Define the root element "EL0" --> <xs:element name="EL0"> <xs:complexType> <xs:sequence> <xs:element name="EL1" type="EL1Type"/> <xs:element name="EL3"> <xs:complexType> <xs:choice> <xs:element ref="EL2_SUBEL1" minOccurs="0" maxOccurs="1"/> <xs:element ref="EL2_SUBEL2" minOccurs="0" maxOccurs="1"/> <xs:element ref="EL2_SUBEL3" minOccurs="0" maxOccurs="1"/> </xs:choice> </xs:complexType> </xs:element> <xs:element name="EL3" type="EL3Type"/> </xs:sequence> <xs:attribute name="type" type="xs:string" use="required"/> </xs:complexType> </xs:element> </xs:schema> ``` --- # 修正后的XSD方案 ### 原XSD主要错误点 1. 属性名称不匹配:EL1的属性写为`id`(应为`attr1`),EL3的属性写为`number`(应为`attr4`) 2. 元素定义错误:缺失EL2的定义,错误用EL3代替;EL3被重复定义 3. 未实现动态子元素逻辑:没有关联EL0的`attr0`值与EL2子元素的对应关系 4. 元素顺序与可选性错误:强制了固定顺序,未满足“任意位置”的需求,也没限制EL3的出现条件 ### 正确XSD代码(基于XSD 1.1,主流处理器均支持) ```xsd <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1"> <!-- EL1类型:带必填attr1属性的空元素 --> <xs:complexType name="EL1Type"> <xs:attribute name="attr1" type="xs:string" use="required"/> </xs:complexType> <!-- EL2_SUBEL1:字符串内容元素 --> <xs:element name="EL2_SUBEL1" type="xs:string"/> <!-- EL2_SUBEL2:带必填attr2属性的空元素 --> <xs:complexType name="EL2_SUBEL2Type"> <xs:attribute name="attr2" type="xs:string" use="required"/> </xs:complexType> <xs:element name="EL2_SUBEL2" type="EL2_SUBEL2Type"/> <!-- EL2_SUBEL3:字符串内容元素 --> <xs:element name="EL2_SUBEL3" type="xs:string"/> <!-- EL3类型:带必填attr4属性的空元素 --> <xs:complexType name="EL3Type"> <xs:attribute name="attr4" type="xs:string" use="required"/> </xs:complexType> <!-- EL2的两种子类型,对应不同attr0值 --> <xs:complexType name="EL2Type1"> <xs:sequence> <xs:element ref="EL2_SUBEL1"/> <xs:element ref="EL2_SUBEL2"/> </xs:sequence> </xs:complexType> <xs:complexType name="EL2Type2"> <xs:sequence> <xs:element ref="EL2_SUBEL3"/> </xs:sequence> </xs:complexType> <!-- 根元素EL0 --> <xs:element name="EL0"> <xs:complexType> <!-- 子元素可任意顺序、重复出现(按需求调整maxOccurs) --> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="EL1" type="EL1Type"/> <xs:element name="EL2"> <!-- 根据父元素attr0值选择EL2的类型 --> <xs:alternative test="../@attr0='type1'" type="EL2Type1"/> <xs:alternative test="../@attr0='type2'" type="EL2Type2"/> </xs:element> <xs:element name="EL3" type="EL3Type"/> </xs:choice> <!-- 限制attr0只能是type1或type2 --> <xs:attribute name="attr0" type="xs:string" use="required"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="type1"/> <xs:enumeration value="type2"/> </xs:restriction> </xs:simpleType> </xs:attribute> <!-- 约束规则:type1不能有EL3,type2必须有EL3;EL1和EL2必须存在 --> <xs:assert test="(@attr0='type1' and not(EL3)) or (@attr0='type2' and EL3)"/> <xs:assert test="EL1 and EL2"/> </xs:complexType> </xs:element> </xs:schema> ``` ### 核心修正说明 1. 匹配需求修正了所有元素和属性的名称 2. 为EL2定义两种专属类型,分别对应`type1`和`type2`的子元素要求 3. 使用XSD 1.1的`xs:alternative`实现属性值驱动的动态类型选择,精准匹配EL2的子元素规则 4. 用`xs:choice + maxOccurs="unbounded"`实现子元素任意顺序的需求 5. 通过`xs:enumeration`限制`attr0`的可选值,用`xs:assert`添加业务约束,确保XML符合示例规则 内容的提问来源于stack exchange,提问作者user1182625)
相关产品推荐
相关产品推荐

