XSD 中的「指示器」(Indicator)是用来控制元素或属性出现顺序和出现次数的工具,一共有三类指示器:
| 指示器类别 | 具体指示器 | 作用对象 | 功能说明 |
|---|---|---|---|
| 顺序指示器(Order Indicators) | xs:all | 只能用于子元素 | 子元素必须有且仅出现一次,但顺序任意(很少用在混合内容中) |
| xs:choice | 子元素 或 属性 | 多个选项中“只能选一个” | |
| xs:sequence | 子元素 或 属性 | 子元素必须“按顺序”出现” | |
| 出现次数指示器(Occurrence Indicators) | minOccurs | 子元素 或 xs:choice/all/sequence | 最小出现次数(默认1) |
| maxOccurs | 子元素 或 xs:choice/all/sequence | 最大出现次数(默认1,可设为 unbounded) | |
| 组指示器(Group Indicators) | xs:group | 用来定义一组可重用的元素 | |
| xs:attributeGroup | 用来定义一组可重用的属性 |
下面用大量真实例子来说明每种指示器的用法和常见组合,尤其是在混合内容场景下怎么用。
1. 顺序指示器(最常用)
| 指示器 | 示例 XML | XSD 写法 |
|---|---|---|
| xs:sequence | 必须先 name,再 age | “`xml |
| xs:choice | 要么 phone,要么 email,不能都有 | xml<br><xs:choice><br> <xs:element name="phone" type="xs:string"/><br> <xs:element name="email" type="xs:string"/><br></xs:choice> |
| xs:all | name 和 age 都必须有,顺序随意 | xml<br><xs:all><br> <xs:element name="name" type="xs:string"/><br> <xs:element name="age" type="xs:integer"/><br></xs:all>注意:xs:all 里每个元素 minOccurs/maxOccurs 只能是 0 或 1 |
2. 出现次数指示器(和顺序指示器一起用)
| 需求 | XSD 关键写法 |
|---|---|
| 元素可选 | <xs:element name="phone" type="xs:string" minOccurs="0"/> |
| 元素可以出现多次 | <xs:element name="phone" type="xs:string" maxOccurs="unbounded"/> |
| 元素至少出现 2 次 | minOccurs="2" maxOccurs="unbounded" |
| choice 组可以出现多次(重要!) | xml<br><xs:choice minOccurs="0" maxOccurs="unbounded"><br> <xs:element name="b"/><br> <xs:element name="i"/><br> <xs:element name="u"/><br></xs:choice> |
3. 混合内容中最常见的指示器组合(必背!)
<xs:complexType name="RichText" mixed="true">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="br"/>
<xs:element name="strong" type="RichText"/> <!-- 递归
<xs:element name="em" type="RichText"/>
<xs:element name="a" type="LinkType"/>
<xs:element name="span" type="RichText"/>
<!-- 继续添加其他内联元素 -->
</xs:choice>
</xs:complexType>
这就是 XHTML、DocBook、DITA 等所有富文本类型的核心写法:
mixed=”true” + xs:choice + maxOccurs=”unbounded”
4. 真实场景对照表
| 场景 | 推荐指示器组合 |
|---|---|
| 个人信息(固定顺序) | <xs:sequence> + 每个元素默认 minOccurs=”1″ maxOccurs=”1″ |
| 联系方式(手机或邮箱任选其一) | <xs:choice> |
| 兴趣爱好(0到多个) | <xs:element name="hobby" type="xs:string" minOccurs="0" maxOccurs="unbounded"/> |
| 富文本段落(混合内容) | mixed="true" + <xs:choice minOccurs="0" maxOccurs="unbounded"> |
| 地址(必须包含省和市,区可选 | <xs:sequence> 里省和市 minOccurs="1",区 minOccurs="0" |
5. 容易出错的点
| 错误写法 | 正确写法 |
|---|---|
| 把 minOccurs/maxOccurs 写在 xs:complexType 上 | 只能写在 <xs:element>、<xs:choice>、<xs:sequence>、<xs:all> 上 |
| 在 xs:all 里面写 maxOccurs=”unbounded” | xs:all 只能 0 或 1 |
| 混合内容里用了 xs:sequence | 混合内容几乎总是用 xs:choice + unbounded 才能让文本随意插入 |
记住一句话:
混合内容永远是:mixed=”true” +
有任何具体的XML结构需要写XSD,贴出来我直接给你写最标准的指示器写法!