我为项目制作了一个简单的UI定义语言,现在想要创建一个模式,以便于验证。不幸的是,我的XSD技能相当生锈,我发现自己试图做一些我甚至不确定的事情。
UI由“块”组成,“块”可以相对于彼此定位。为了简化最常见的用例,我希望引用属性能够包含任何字符串parent
,previous
或next
。为了尽可能灵活,我还希望它能够指向具有ID的任何元素。
换句话说,我希望以下内容有效:
<ui>
<block id="foo"/>
<block/>
<block anchor="previous"/>
<block anchor="#foo"/>
</ui>
我如何在XSD中描述这个?
答案 0 :(得分:1)
事实证明,XSD包含一个完全符合这一功能的功能 - 结合了两种或更多种类型 - 而我只是错过了它。 union
创建一个类型,其词法空间覆盖其所有成员类型的词法空间(换句话说,它可以包含与其任何子类型匹配的值)。
警告IDREF
s不能包含前导#
(它是对ID的直接引用,而不是URL的片段标识符),以下架构将验证该示例XML。有趣的位是AnchorType
和TreeReferenceType
。
<schema targetNamespace="urn:x-ample:ui" elementFormDefault="qualified" xmlns="http://www.w3.org/2001/XMLSchema" xmlns:ui="urn:x-ample:ui">
<element name="ui" type="ui:UIType"/>
<complexType name="UIType">
<sequence>
<element minOccurs="1" maxOccurs="unbounded" name="block" type="ui:BlockType"/>
</sequence>
</complexType>
<complexType name="BlockType">
<attribute use="optional" name="id" type="ID"/>
<attribute name="anchor" type="ui:AnchorType"/>
</complexType>
<simpleType name="AnchorType">
<union memberTypes="ui:TreeReferenceType IDREF"/>
</simpleType>
<simpleType name="TreeReferenceType">
<restriction base="string">
<enumeration value="parent"/>
<enumeration value="previous"/>
<enumeration value="next"/>
</restriction>
</simpleType>
</schema>