XSD 对于复杂的 XML 结构
XSD for complex XML structure
我正在尝试验证一个相当复杂的 XML 结构,但我似乎无法想出一个 XSD 结构来表达以下内容:
<foo fooAttribute1="..." fooAttribute2="..." ...>
<bar1 id="1" ... />
<bar1 id="2" ... />
<bar2 id="1" ... />
<bar2 id="2" ... />
<![MyFormattedTextGoesHere[foo text goes here]]>
</foo>
所以,我想要一个 foo
,其中 可以 包含
- 属性
- 0..*
bar1
个元素
- 0..*
bar2
个元素
- 格式化 文本(例如,以
<![MyFormattedTextGoesHere[
开头并以 ]]>
结尾
相关说明:我还可以像这样验证属性 values 吗:
<xml someAttribute=$... />
(必须以 $
开头)?
我目前拥有的是
<xs:element name="foo" minOccurs="0" maxOccurs="unbounded">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element name="bar1" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" form="unqualified" type="xs:string" />
<xs:attribute name="..." form="unqualified" type="xs:string" />
</xs:complexType>
</xs:element>
<xs:element name="bar2" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" form="unqualified" type="xs:string" />
<xs:attribute name="..." form="unqualified" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="fooAttribute1" form="unqualified" type="xs:string"/>
<xs:attribute name="fooAttribute2" form="unqualified" type="xs:string"/>
<xs:attribute name="..." form="unqualified" type="xs:string" />
<!-- accept/validate text here? -->
</xs:complexType>
<!-- or here? -->
</xs:element>
上面的 XML 格式不正确,因为 <!
后跟一般文本。这里的意思可能是CDATA部分,像这样:
<?xml version="1.0" encoding="UTF-8"?>
<foo fooAttribute1="$..." fooAttribute2="..." >
<bar1 id="1" />
<bar1 id="2" />
<bar2 id="1" />
<bar2 id="2" />
<![CDATA[MyFormattedTextGoesHere[foo text goes here]]>
</foo>
上述 XML 有效的模式的一个很好的起点是:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:simpleType name="beginswithdollar">
<xs:restriction base="xs:string">
<xs:pattern value="$.*"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="foo">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element name="bar1" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence/>
<xs:attribute name="id" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="bar2" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence/>
<xs:attribute name="id" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="fooAttribute1" type="beginswithdollar"/>
<xs:anyAttribute processContents="lax"/>
</xs:complexType>
</xs:element>
</xs:schema>
XML 架构不支持一些内容:
- XML 架构看不到文本是否在 CDATA 部分中。 CDATA 部分用于避免转义特殊字符。
- 复杂类型可以是混合内容,也可以不是。如果是混合内容,则无法控制文本出现的位置或其类型:它也可能出现在
bar*
个元素之前或之间。
xs:anyAttribute
可以允许属性不受限制,但通常无法限制它们的类型。例如,在上面的架构中,属性 fooAttribute1
必须以美元开头,而任何其他属性都可以不受限制。
如果支持 XML Schema 1.1,还有 assert
功能允许表达用户定义的约束。这可能是一种以定制的方式进一步限制实例有效性的方法,超出了其他 XML 模式组件可以做的。
我正在尝试验证一个相当复杂的 XML 结构,但我似乎无法想出一个 XSD 结构来表达以下内容:
<foo fooAttribute1="..." fooAttribute2="..." ...>
<bar1 id="1" ... />
<bar1 id="2" ... />
<bar2 id="1" ... />
<bar2 id="2" ... />
<![MyFormattedTextGoesHere[foo text goes here]]>
</foo>
所以,我想要一个 foo
,其中 可以 包含
- 属性
- 0..*
bar1
个元素 - 0..*
bar2
个元素 - 格式化 文本(例如,以
<![MyFormattedTextGoesHere[
开头并以]]>
结尾
相关说明:我还可以像这样验证属性 values 吗:
<xml someAttribute=$... />
(必须以 $
开头)?
我目前拥有的是
<xs:element name="foo" minOccurs="0" maxOccurs="unbounded">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element name="bar1" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" form="unqualified" type="xs:string" />
<xs:attribute name="..." form="unqualified" type="xs:string" />
</xs:complexType>
</xs:element>
<xs:element name="bar2" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="id" form="unqualified" type="xs:string" />
<xs:attribute name="..." form="unqualified" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="fooAttribute1" form="unqualified" type="xs:string"/>
<xs:attribute name="fooAttribute2" form="unqualified" type="xs:string"/>
<xs:attribute name="..." form="unqualified" type="xs:string" />
<!-- accept/validate text here? -->
</xs:complexType>
<!-- or here? -->
</xs:element>
上面的 XML 格式不正确,因为 <!
后跟一般文本。这里的意思可能是CDATA部分,像这样:
<?xml version="1.0" encoding="UTF-8"?>
<foo fooAttribute1="$..." fooAttribute2="..." >
<bar1 id="1" />
<bar1 id="2" />
<bar2 id="1" />
<bar2 id="2" />
<![CDATA[MyFormattedTextGoesHere[foo text goes here]]>
</foo>
上述 XML 有效的模式的一个很好的起点是:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:simpleType name="beginswithdollar">
<xs:restriction base="xs:string">
<xs:pattern value="$.*"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="foo">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element name="bar1" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence/>
<xs:attribute name="id" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="bar2" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence/>
<xs:attribute name="id" type="xs:string"/>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="fooAttribute1" type="beginswithdollar"/>
<xs:anyAttribute processContents="lax"/>
</xs:complexType>
</xs:element>
</xs:schema>
XML 架构不支持一些内容:
- XML 架构看不到文本是否在 CDATA 部分中。 CDATA 部分用于避免转义特殊字符。
- 复杂类型可以是混合内容,也可以不是。如果是混合内容,则无法控制文本出现的位置或其类型:它也可能出现在
bar*
个元素之前或之间。 xs:anyAttribute
可以允许属性不受限制,但通常无法限制它们的类型。例如,在上面的架构中,属性fooAttribute1
必须以美元开头,而任何其他属性都可以不受限制。
如果支持 XML Schema 1.1,还有 assert
功能允许表达用户定义的约束。这可能是一种以定制的方式进一步限制实例有效性的方法,超出了其他 XML 模式组件可以做的。