XSD定义家庭XML结构遇maxOccurs错误,求正确实现方案
家庭XSD定义问题及解决办法
问题背景
需要定义一个描述家庭结构的XSD,满足以下要求:
MumsName、DadsName元素可选,且出现顺序不限child元素可出现0至多次
示例XML如下:
<family> <DadsName>Fred</DadsName> <MumsName>Wilma</MumsName> <child> <childName>pebbles</childName> </child> <child> <childName>BamBam</childName> </child> </family>
编写的XSD尝试用<xs:all>实现无序要求,但出现错误:The maxOccurs attribute is invalid. The value unBounded is invalid according to its datatype Union,代码如下:
<xs:element name="family"> <xs:complexType> <xs:all> <xs:element name="DadsName" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="MumsName" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="child" maxOccurs="unbounded" > <xs:complexType> <xs:sequence> <xs:element name="childName" type="xs:string"/> <xs:element name="childAge" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:all> </xs:complexType> </xs:element>
错误原因
当前XSD不正确,问题出在<xs:all>的使用限制上:
在XSD 1.0规范中,<xs:all>的子元素maxOccurs只能设置为0或1,不允许使用unbounded或大于1的数值。你给child元素设置maxOccurs="unbounded",直接违反了这个规则,所以报错。
解决方案
有两种可行的解决方式:
方式1:使用XSD 1.1规范(需解析器支持)
XSD 1.1放宽了<xs:all>的限制,允许子元素设置maxOccurs="unbounded"或大于1的值。只需在XSD开头声明使用1.1版本即可,修改后的XSD如下:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.1"> <xs:element name="family"> <xs:complexType> <xs:all> <xs:element name="DadsName" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="MumsName" type="xs:string" minOccurs="0" maxOccurs="1"/> <xs:element name="child" maxOccurs="unbounded"> <xs:complexType> <xs:sequence> <xs:element name="childName" type="xs:string"/> <xs:element name="childAge" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:all> </xs:complexType> </xs:element> </xs:schema>
注意:需要确保你的XML解析器支持XSD 1.1(比如Saxon 9.5+)。
方式2:用<xs:choice>模拟无序结构(兼容XSD 1.0)
如果必须兼容XSD 1.0,可以使用<xs:choice>并设置maxOccurs="unbounded",同时给每个可选元素设置maxOccurs="1",以此实现无序且允许重复child的需求:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="family"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element name="DadsName" type="xs:string" maxOccurs="1"/> <xs:element name="MumsName" type="xs:string" maxOccurs="1"/> <xs:element name="child"> <xs:complexType> <xs:sequence> <xs:element name="childName" type="xs:string"/> <xs:element name="childAge" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> </xs:schema>
这种方式下,DadsName和MumsName最多各出现一次,child可以出现任意次数,且所有元素的顺序不受限制,完全符合需求。
内容的提问来源于stack exchange,提问作者JPO
相关产品推荐
相关产品推荐

