XML受限元素添加ID属性失败问题求助
问题描述
原本有一套可正常运行的XML/XSD文件,想要为多个具有特定值限制的受限元素添加ID属性。将Widget和Sprocket从simpleType修改为complexType并添加属性后,出现以下错误:
31:37 s4s-elt-invalid-content.1: The content of '#AnonType_Widget' is invalid. Element 'restriction' is invalid, misplaced, or occurs too often.
49:37 s4s-elt-invalid-content.1: The content of '#AnonType_Sprocket' is invalid. Element 'restriction' is invalid, misplaced, or occurs too often.
尝试在complexType内创建simpleType、引用独立ID条目等多种方法均未解决问题。以下是修改前后的代码:
修改后的XML和XSD
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test.xsd"> <Widgets> <Widget ID="0">A</Widget> <Widget ID="1">B</Widget> </Widgets> <Sprockets> <Sprocket ID="0">X</Sprocket> <Sprocket ID="1">Y</Sprocket> </Sprockets> </Configuration>
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="Configuration"> <xs:complexType> <xs:sequence> <xs:element ref="Widgets" minOccurs="1" maxOccurs="1"/> <xs:element ref="Sprockets" minOccurs="1" maxOccurs="1"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="Widgets"> <xs:complexType> <xs:sequence> <xs:element ref="Widget" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="Sprockets"> <xs:complexType> <xs:sequence> <xs:element ref="Sprocket" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="Widget"> <xs:complexType> <xs:restriction base="xs:string"> <xs:enumeration value="A"/> <xs:enumeration value="B"/> <xs:enumeration value="C"/> </xs:restriction> <xs:attribute name="ID" use="optional"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="([0-9])*"/> <xs:minLength value="1"/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:complexType> </xs:element> <xs:element name="Sprocket"> <xs:complexType> <xs:restriction base="xs:string"> <xs:enumeration value="X"/> <xs:enumeration value="Y"/> <xs:enumeration value="Z"/> </xs:restriction> <xs:attribute name="ID" use="required"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="([0-9])*"/> <xs:minLength value="1"/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:complexType> </xs:element> </xs:schema>
原始XML和XSD
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="test.xsd"> <Widgets> <Widget>A</Widget> <Widget>B</Widget> </Widgets> <Sprockets> <Sprocket>X</Sprocket> <Sprocket>Y</Sprocket> </Sprockets> </Configuration>
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="Configuration"> <xs:complexType> <xs:sequence> <xs:element ref="Widgets" minOccurs="1" maxOccurs="1"/> <xs:element ref="Sprockets" minOccurs="1" maxOccurs="1"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="Widgets"> <xs:complexType> <xs:sequence> <xs:element ref="Widget" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="Sprockets"> <xs:complexType> <xs:sequence> <xs:element ref="Sprocket" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="Widget"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="A"/> <xs:enumeration value="B"/> <xs:enumeration value="C"/> </xs:restriction> </xs:simpleType> </xs:element> <xs:element name="Sprocket"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="X"/> <xs:enumeration value="Y"/> <xs:enumeration value="Z"/> </xs:restriction> </xs:simpleType> </xs:element> </xs:schema>
解决方案
错误原因是:complexType不能直接包含restriction元素。当需要给原本是simpleType的元素(仅含文本内容)添加属性时,必须用xs:simpleContent包裹restriction或extension,才能同时保留文本内容的限制规则和新增属性。
修正后的XSD代码如下:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="Configuration"> <xs:complexType> <xs:sequence> <xs:element ref="Widgets" minOccurs="1" maxOccurs="1"/> <xs:element ref="Sprockets" minOccurs="1" maxOccurs="1"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="Widgets"> <xs:complexType> <xs:sequence> <xs:element ref="Widget" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="Sprockets"> <xs:complexType> <xs:sequence> <xs:element ref="Sprocket" minOccurs="0" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="Widget"> <xs:complexType> <xs:simpleContent> <xs:restriction base="xs:string"> <xs:enumeration value="A"/> <xs:enumeration value="B"/> <xs:enumeration value="C"/> </xs:restriction> </xs:simpleContent> <xs:attribute name="ID" use="optional"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="([0-9])*"/> <xs:minLength value="1"/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:complexType> </xs:element> <xs:element name="Sprocket"> <xs:complexType> <xs:simpleContent> <xs:restriction base="xs:string"> <xs:enumeration value="X"/> <xs:enumeration value="Y"/> <xs:enumeration value="Z"/> </xs:restriction> </xs:simpleContent> <xs:attribute name="ID" use="required"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="([0-9])*"/> <xs:minLength value="1"/> </xs:restriction> </xs:simpleType> </xs:attribute> </xs:complexType> </xs:element> </xs:schema>
关键修改点
- 给每个包含restriction的complexType添加了
xs:simpleContent标签,将restriction包裹其中,既保留原文本内容的枚举限制,又合法添加了ID属性。 - 该结构符合XSD规范:当complexType同时包含简单文本内容和属性时,必须通过simpleContent定义内容部分的约束规则。
内容的提问来源于stack exchange,提问作者Siili
相关产品推荐
相关产品推荐

