<xsd:simpleType name="MaritalStatusEnumType">
<xsd:restriction base="xsd:normalizedString">
<xsd:enumeration value="porced"/>
<xsd:enumeration value="Married"/>
<xsd:enumeration value="NeverMarried"/>
<xsd:enumeration value="Separated"/>
<xsd:enumeration value="SignificantOther"/>
<xsd:enumeration value="Widowed"/>
<xsd:enumeration value="Unknown"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:element name="MaritalStatus" type="MaritalStatusEnumType"/>
假设一个公司要使用这些值,另外,还要支持它的重要贸易伙伴使用另一个值。CivilUnion 是一个扩展值,公司识别出该值不属于原始模式。但是从语义上来说,使用现有元素 —MaritalStatus — 也是可以的。公司要如何实现呢?
回页首
解决方案 1: 编辑原始模式使其包含新枚举值
当然,编辑原始模式使其包含新枚举值是最直接的方法。保留模式的本地副本,然后编辑这些模式以支持公司使用的枚举值。
优点:易于实现
缺点:
需要编辑原始模式,这些模式将逐渐改变,以至于无法控制。如果扩展一个先前存在的列表,那么创建者(贸易伙伴、协会等)可能要发布列表的新版本。您需要将编辑的内容传播到每个新版本中。
手动编辑模式会导致意外的编辑错误。
如果您不能(或不想)编辑原始模式,则需要一种替代方法。
回页首
解决方案 2: 创建新枚举列表并加入到原始列表中
第二个选择是创建新枚举列表,并将其加入到原始枚举列表中。清单 1 显示原始婚姻状况列表。清单 2 显示最新创建的枚举列表。
清单 2. 新婚姻状况枚举列表
<xsd:simpleType name="MyExtMaritalStatusEnumType">
<xsd:restriction base="xsd:normalizedString">
<xsd:enumeration value="CivilUnion"/>
</xsd:restriction>
</xsd:simpleType>
使用 <xsd:union> 标记将其与原始列表结合,如 清单 3 所示。
清单 3. 将两个列表组合起来
<xsd:simpleType name="MaritalStatusType_Union">
<xsd:union memberTypes="MyExtMaritalStatusEnumType MaritalStatusEnumType"/>
</xsd:simpleType>
<xsd:element name="MaritalStatus" type="MaritalStatusType_Union"/>
该解决方案仍然需要对模式进行编辑 — 即将元素 MaritalStatus 由 MaritalStatusType 类型转换为 MaritalStatusType_Union 类型。改动不大,但仍然有一些手动编辑工作。
优点:不改变原始枚举列表。
缺点:
在设计阶段所有的值必须是已知的,防止后期绑定解决方案。
需要 <xsd:union> 标记支持,但有时该标记无法用工具实现。
回页首
解决方案 3: 创建一个模式,并与原始枚举类型结合
现在看一下有关眼睛颜色的人口数据用例。清单 4 显示这一列表。
清单 4. Person Eye Color 枚举列表
<xsd:simpleType name="PersonEyeColorType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Black"/>
<xsd:enumeration value="Hazel"/>
<xsd:enumeration value="Gray"/>
<xsd:enumeration value="Brown"/>
<xsd:enumeration value="Violet"/>
<xsd:enumeration value="Green"/>
<xsd:enumeration value="Blue"/>
<xsd:enumeration value="Maroon"/>
<xsd:enumeration value="Pink"/>
<xsd:enumeration value="Dichromatic"/>
<xsd:enumeration value="Unknown"/>
</xsd:restriction>
</xsd:simpleType>
接下来,创建采用新值的模式(一个正则表达式)。该模式是以 x: 为前缀的任意字符串。x: 是标准枚举列表和扩展列表之间的描绘程序。清单 5 显示这一模式。
清单 5. 用于扩展的正则表达式
<xsd:simpleType name="StringPatternType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="x:\S.*"/>
</xsd:restriction>
</xsd:simpleType>
最后,使用 <xsd:union> 标记结合列表与模式,如 清单 6 所示。
清单 6. 枚举列表与扩展模式的结合
<xsd:simpleType name="MyExtPersonEyeColorType">
<xsd:union memberTypes="PersonEyeColorType StringPatternType"/>
</xsd:simpleType>
<xsd:element name="PersonEyeColor" type="MyExtPersonEyeColorType"/>
同一节点拥有标准和扩展值。两个值很容易分离,而且都可以用解析器验证,如 清单 7 所示。
清单 7. XML 实例样例
<PersonEyeColor>Black</PersonEyeColor>
<PersonEyeColor>x:Teal</PersonEyeColor>
优点:
同一元素可用于所有数据。
用解析器对基本枚举列表进行验证。
清晰地分隔扩展值。
该解决方案允许在以后绑定新值。
缺点:
必须解析元素的内容,以确定是否已经被扩展。
模式解析器必须支持正则表达式。
需要 <xsd:union> 标记支持。
回页首
解决方案 4:使用单独的字段用于扩展
在该解决方案中,枚举字段不会变化。然而,您要在模式中设计一个扩展字段来容纳附加值。在本例中,初始列表是依赖型的(就业受益者和受养人之间的关系),如 清单 8 所示。
清单 8. 依赖关系枚举列表
<xsd:simpleType name="DependentRelationshipEnumType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="AdoptedChild"/>
<xsd:enumeration value="Brother"/>
<xsd:enumeration value="Child"/>
<xsd:enumeration value="ExSpouse"/>
<xsd:enumeration value="Father"/>
<xsd:enumeration value="Granddaughter"/>
<xsd:enumeration value="Grandson"/>
<xsd:enumeration value="Grandfather"/>
<xsd:enumeration value="Grandmother"/>
<xsd:enumeration value="LifePartner"/>
<xsd:enumeration value="Mother"/>
<xsd:enumeration value="Sister"/>
<xsd:enumeration value="Spouse"/>
<xsd:enumeration value="Extension"/>
</xsd:restriction>
</xsd:simpleType>
需要一个能够容纳新值的附加属性 — extension—。清单 9 显示了该属性。
清单 9. 依赖关系的 extension 属性
<xsd:complexType name="DependentRelationshipType">
<xsd:simpleContent>
<xsd:extension base="DependentRelationshipEnumType">
<xsd:attribute name="extension" type="xsd:string"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:element name="DependentRelationship" type="DependentRelationshipType"/>
清单 10 显示一些反映 extension 的 XML 实例。
清单 10. 示例 XML 实例
<DependentRelationship>Child</DependentRelationship>
<DependentRelationship extension="MyNewRelationship">Extension</DependentRelationship>
优点:
不需要编辑原始模式。
该解决方案允许在以后绑定新值。
在原始模式中显式设计 extension 方法。
缺点:
在设计阶段,必须在每个枚举列表中设计 extension 方法。
必须在元素中而不是在属性中设置枚举值。
回页首
解决方案 5: 基于文档的方法 —— 与字符串结合
注意:解决方案 5 和解决方案 6 违反了在一个周期内进行验证 这一要求。但是,我之所以在这里介绍它们,是因为在很多实际环境中可以使用这些方法。
在第 5 个解决方案中,使用 <xsd:union> 标记将枚举列表与字符串结合。实际上,该解决方案提示接收系统哪些值是标准的(包括包装和拼写)。但实际上字符串字段可以存放任何值。因此,解析器并不验证值。相反,这些值在第二个周期或者在接收数据的应用程序中验证。有些 XML 组织就使用这样的方案。
清单 11 显示通过 <xsd:union> 将一个枚举列表和 <xsd:string> 结合。因为任意值都可以是一个字符串,所以不用验证枚举列表。这些值建议使用标准值。
清单 11. 与字符串结合的 DayOfWeek 枚举列表
<xsd:simpleType name="DayOfWeekEnumType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Sunday"/>
<xsd:enumeration value="Monday"/>
<xsd:enumeration value="Tuesday"/>
<xsd:enumeration value="Wednesday"/>
<xsd:enumeration value="Thursday"/>
<xsd:enumeration value="Friday"/>
<xsd:enumeration value="Saturday"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:element name="DayOfWeek" type="DayOfWeekEnumType"/>
<xsd:simpleType name="ExtendedDayOfWeekType">
<xsd:union memberTypes="DayOfWeekEnumType xsd:string"/>
</xsd:simpleType>
<xsd:element name="DayOfWeek_solution5" type="ExtendedDayOfWeekType"/>
优点:可以添加任意的扩展值,即使在后期绑定时也可以添加。
缺点:
解析器不验证枚举值,在第二个步骤中才进行验证。
需要 <xsd:union> 标记支持。
回页首
解决方案 6: 基于文档的方法 —— 使用 <xsd:annotation>
要使用该方法,将实际的枚举值放到 <xsd:documentation> 标记内,同时将数据字段保留为一个简单字符串。清单 12 显示枚举值。
清单 12. 在 <xsd:documentation> 标记内的枚举值
<xsd:element name="DayOfWeek" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
<!-- suggested enumerations -->
<xsd:enumeration value="Sunday"/>
<xsd:enumeration value="Monday"/>
<xsd:enumeration value="Tuesday"/>
<xsd:enumeration value="Wednesday"/>
<xsd:enumeration value="Thursday"/>
<xsd:enumeration value="Friday"/>
<xsd:enumeration value="Saturday"/>
</xsd:documentation>
</xsd:annotation>
</xsd:element>
优点:
可以添加任意的扩展值,即使在后期绑定时也可以添加。
只需要最简单的 XML 模式特性。
缺点:解析器不验证枚举值。
回页首
未讨论的方法
我省略了其他几种扩展枚举列表的解决方案。下面简单介绍了两种没有使用的方法:
使用 <xsd:redefine> 标记: 通常不使用 XML 模式的这一特性,而且一般无法用工具实现它。该方法经常被认为是避免重新定义的最佳实践。
使用 substitutionGroup 元素替换包含所有值的联合列表: 另外一种出色的解决方案,使用了替换组和联合。将原始列表与新列表联合以创建一个完整的枚举列表,然后使用 substitutionGroups 标记(或 <xsi:type> 标记)替换一个全局作用域元素。该方法的缺点是替换不能派生有效的联合,替换需要两个组件来自相同的基类型。扩展和限制是替换的两个有效方法。但是,根据 XML 模式规范,联合并不是有效的派生技术(参阅 参考资料)。
回页首
结束语
XML 模式设计者和实现人员需要一种方法来扩展现有的枚举列表。因为一旦原始列表创建后,规范不允许进行扩展,因此需要找到一种方法实际实现扩展。实现人员可以使用本文的示例来设计和扩展枚举列表。每种方法都有优缺点,没有一种方法在所有用例中都是最佳方法。那么,应该使用哪种方法呢?
请考虑这些经验法则:
如果您习惯编辑原始枚举列表或模式,而且在设计阶段就知道所有要扩展的枚举值,最好使用 解决方案 1(手动编辑原始列表)或 解决方案 2(创建新列表并加入到原始列表中)。
如果想使用相同的语义元素来包含基本枚举列表和扩展枚举列表,可以考虑 解决方案 3(与模式联合)。
如果允许原始列表与扩展列表有不同的字段,可以使用 解决方案 4(独立的字段)。
如果不想在解析器中解析枚举值,可以考虑 Genericode 方法或使用 解决方案 5 或 解决方案 6。
这些指导原则可以使模式设计者找到实用的最佳实践,而且可以帮助他们创建易于实现、可扩展的枚举列表。
XML 模式和 XML 实例示例 ExtendEnumeratedListsCode.zip 2KB
以上就是在XML模式中扩展枚举列表的示例代码详解的详细内容,更多请关注php中文网其它相关文章!
声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
程序员必备接口测试调试工具:点击使用
Apipost = Postman + Swagger + Mock + Jmeter
Api设计、调试、文档、自动化测试工具
网页生成APP,用做网站的技术去做APP:立即创建
手机网站开发APP、自助封装APP、200+原生模块、2000+映射JS接口按需打包
相关文章
相关视频