求助:如何在XSD中基于父元素属性名条件验证子元素值长度
正确实现XSD 1.1条件约束(根据tag的name属性控制value是否允许为空)
原XSD 1.1修改的问题
你之前的修改存在几个关键错误,导致约束未生效:
- 语法错误:
value元素的type:"xs:string"是笔误,应该用等号type="xs:string" - XPath表达式错误:判断
name属性值时,字符串字面量需要用单引号包裹,比如@name = 'token'而非@name = token - 冗余定义:
optional类型无需额外定义,xs:string本身允许空值(minLength默认0)
方案1:使用XSD 1.1的xs:alternative(修正版)
这种方式通过为value元素指定不同的类型替代规则,根据父元素的name属性动态切换约束:
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1"> <xs:element name="nodes"> <xs:complexType> <xs:sequence> <xs:element ref="node" maxOccurs="unbounded" minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="node"> <xs:complexType> <xs:sequence> <xs:element name="tag" maxOccurs="unbounded" type="tagType" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:unique name="TagUniquenessCheck"> <xs:selector xpath="tag"/> <xs:field xpath="@name"/> </xs:unique> </xs:element> <!-- 定义必填的字符串类型(非空) --> <xs:simpleType name="mandatoryString"> <xs:restriction base="xs:string"> <xs:minLength value="1"/> </xs:restriction> </xs:simpleType> <xs:complexType name="tagType"> <xs:sequence> <xs:element name="value"> <!-- 当name为token时,使用默认xs:string(允许空) --> <xs:alternative test="../@name = 'token'" type="xs:string"/> <!-- 其他情况使用非空约束 --> <xs:alternative test="../@name != 'token'" type="mandatoryString"/> <!-- 兜底规则,确保覆盖所有情况 --> <xs:alternative type="mandatoryString"/> </xs:element> </xs:sequence> <xs:attribute name="name" use="required"> <xs:simpleType> <xs:restriction base="xs:NMTOKEN"> <xs:enumeration value="id"/> <xs:enumeration value="client"/> <xs:enumeration value="section"/> <xs:enumeration value="token"/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:complexType> </xs:schema>
注:../@name用于从value元素向上定位到父tag的name属性,确保XPath路径正确。
方案2:使用XSD 1.1的xs:assert(更直观的条件断言)
如果觉得类型替代不够直观,可以用xs:assert直接在tagType中添加条件约束,逻辑更清晰:
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1"> <xs:element name="nodes"> <xs:complexType> <xs:sequence> <xs:element ref="node" maxOccurs="unbounded" minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="node"> <xs:complexType> <xs:sequence> <xs:element name="tag" maxOccurs="unbounded" type="tagType" minOccurs="0"/> </xs:sequence> </xs:complexType> <xs:unique name="TagUniquenessCheck"> <xs:selector xpath="tag"/> <xs:field xpath="@name"/> </xs:unique> </xs:element> <xs:complexType name="tagType"> <xs:sequence> <xs:element name="value" type="xs:string"/> </xs:sequence> <xs:attribute name="name" use="required"> <xs:simpleType> <xs:restriction base="xs:NMTOKEN"> <xs:enumeration value="id"/> <xs:enumeration value="client"/> <xs:enumeration value="section"/> <xs:enumeration value="token"/> </xs:restriction> </xs:simpleType> </xs:attribute> <!-- 断言逻辑:要么是token类型(允许空),要么是非token类型且value非空 --> <xs:assert test="(@name != 'token' and string-length(value) > 0) or @name = 'token'"/> </xs:complexType> </xs:schema>
验证规则说明
- 对于
name="id"/client/section的tag:value为空或空白字符会触发验证错误 - 对于
name="token"的tag:value可以为空(包括空白字符),也可以有有效值
内容的提问来源于stack exchange,提问作者Vithursa Mahendrarajah
相关产品推荐
相关产品推荐

