在列表中添加新值是一种常见而且必要的需求。模式设计者通常希望在系统架构中构建一种添加附加值的方法,并且该附加值在设计阶段是未知的。模式设计者如何创建一个可扩展、易于实现的枚举值列表?本文将介绍几种实现这一目标的方法。
模式设计者和实现人员需要一种扩展 XML 模式中现有枚举列表的方法。不幸的是,XML 模式规范不允许在这些列表的创建过程中(参阅 参考资料)进行扩展。设计阶段所选的值是固定的,而且都是可用的。尽管有这样的限制,人们仍使用各种替代方案来实现列表扩展。很多使用现有的不能改变的模式的客户经常提出这一要求。他们希望在添加新功能的同时保持向后兼容性。本文中,您将会看到模式设计者如何克服障碍实现该功能。
枚举列表 是特定数据点的一组指定值。例如,您也许通过固定的值列表查看国家代码,包括 DE(德国)、US(美国)和 JP(日本)。根据给定的值集,当一个新国家被识别出时,如 TL(东帝汶)或者 BA(波斯尼亚及黑塞哥维那),该怎么办?使用以前的名称列表的客户必须改变实现来容纳新值。
当使用 XML 模式对数据建模时,枚举值被显式列出。因此,国家代码列表依次包含各个枚举值。经常需要识别列表中的新值,而且必须将其容纳到列表中,模式设计者试图找到一种扩展列表的方法,实际上,是将这种方法构建到设计中,允许添加在设计时未知的附加值。
创建可扩展的枚举列表
在寻找这一问题的解决方案时,受到四个关键标准的影响:
首先,要在设计阶段之后扩展列表。不管是快速建立一个新的贸易伙伴还是建立时间关键型的新数据字段,在关键时刻进行扩展是一项实际需求。
其次,能够在解析器中验证值对于简化实现是非常关键的。
第三,在单个周期内完成解析和验证是至关重要的。这就避免了像 Genericode 解决方案一样,在一个单独的周期和解析器中进行验证。对于某些设置来说,添加新技术需求会导致成本太高或者太耗时。
最后,解决方案必须能够向后兼容原始的模式。不兼容的列表更改不能称为扩展。
有些人认为根本就不应该扩展枚举列表。数据建模人员也许认为如果想让模型包含更多数据、扩展模型,那么可以根据产品创建模式 — 实际上,在需要时创建更大的模型并减少限制。如果能够控制原始模式和数据模型,这样做是可以的,这种方法也许是理想的方法。但是,如果您需要在设计阶段之后进行实际扩展,这样的方法是行不通的。
还有人认为扩展枚举列表的关键是不使用 XML 模式验证解析器。Genericode(参阅 参考资料)建议在第二层对枚举列表进行验证,脱离初始的 XML 模式解析器验证过程。这种理论是正确的,而且这种方法的应用会越来越广泛。但是,如果要在一个解析周期内完成,这种解决方案是无法做到的。在某些情况下,不可能执行第二个验证周期。
当然,您可以在新列表中创建新元素。但是,不能向后兼容原始模式。我们的目标是在保持向后兼容性的同时实现一个可扩展的列表(参阅 参考资料)。
对于本文的目标,这里作出的假设基于我与客户打交道的经验 —— 即用附加值扩展现有枚举列表的需求。另外,我假设在一个步骤内完成 XML 模式解析与验证等操作。
扩展枚举列表的必要条件
该扩展示例有四个必要条件:
允许在设计阶段之后扩展枚举列表。
用解析器验证枚举列表。
在一个周期内验证枚举列表。
维持和原始模式的向后兼容性。
举例来说,一个团队需要处理一个区域产业协会的枚举列表(或任意现有列表)为例,并根据使用修改模式组件。先前的模式提供 MaritalStatus 组件和值的枚举列表,如 清单 1 所示。
清单 1. 婚姻状况枚举列表
<xsd:simpleType name="MaritalStatusEnumType">
<xsd:restriction base="xsd:normalizedString">
<xsd:enumeration value="Divorced"/>
<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. 依赖关系枚举列表
上一页12 下一页 阅读全文
模式设计者和实现人员需要一种扩展 XML 模式中现有枚举列表的方法。不幸的是,XML 模式规范不允许在这些列表的创建过程中(参阅 参考资料)进行扩展。设计阶段所选的值是固定的,而且都是可用的。尽管有这样的限制,人们仍使用各种替代方案来实现列表扩展。很多使用现有的不能改变的模式的客户经常提出这一要求。他们希望在添加新功能的同时保持向后兼容性。本文中,您将会看到模式设计者如何克服障碍实现该功能。
枚举列表 是特定数据点的一组指定值。例如,您也许通过固定的值列表查看国家代码,包括 DE(德国)、US(美国)和 JP(日本)。根据给定的值集,当一个新国家被识别出时,如 TL(东帝汶)或者 BA(波斯尼亚及黑塞哥维那),该怎么办?使用以前的名称列表的客户必须改变实现来容纳新值。
当使用 XML 模式对数据建模时,枚举值被显式列出。因此,国家代码列表依次包含各个枚举值。经常需要识别列表中的新值,而且必须将其容纳到列表中,模式设计者试图找到一种扩展列表的方法,实际上,是将这种方法构建到设计中,允许添加在设计时未知的附加值。
创建可扩展的枚举列表
在寻找这一问题的解决方案时,受到四个关键标准的影响:
首先,要在设计阶段之后扩展列表。不管是快速建立一个新的贸易伙伴还是建立时间关键型的新数据字段,在关键时刻进行扩展是一项实际需求。
其次,能够在解析器中验证值对于简化实现是非常关键的。
第三,在单个周期内完成解析和验证是至关重要的。这就避免了像 Genericode 解决方案一样,在一个单独的周期和解析器中进行验证。对于某些设置来说,添加新技术需求会导致成本太高或者太耗时。
最后,解决方案必须能够向后兼容原始的模式。不兼容的列表更改不能称为扩展。
有些人认为根本就不应该扩展枚举列表。数据建模人员也许认为如果想让模型包含更多数据、扩展模型,那么可以根据产品创建模式 — 实际上,在需要时创建更大的模型并减少限制。如果能够控制原始模式和数据模型,这样做是可以的,这种方法也许是理想的方法。但是,如果您需要在设计阶段之后进行实际扩展,这样的方法是行不通的。
还有人认为扩展枚举列表的关键是不使用 XML 模式验证解析器。Genericode(参阅 参考资料)建议在第二层对枚举列表进行验证,脱离初始的 XML 模式解析器验证过程。这种理论是正确的,而且这种方法的应用会越来越广泛。但是,如果要在一个解析周期内完成,这种解决方案是无法做到的。在某些情况下,不可能执行第二个验证周期。
当然,您可以在新列表中创建新元素。但是,不能向后兼容原始模式。我们的目标是在保持向后兼容性的同时实现一个可扩展的列表(参阅 参考资料)。
对于本文的目标,这里作出的假设基于我与客户打交道的经验 —— 即用附加值扩展现有枚举列表的需求。另外,我假设在一个步骤内完成 XML 模式解析与验证等操作。
扩展枚举列表的必要条件
该扩展示例有四个必要条件:
允许在设计阶段之后扩展枚举列表。
用解析器验证枚举列表。
在一个周期内验证枚举列表。
维持和原始模式的向后兼容性。
举例来说,一个团队需要处理一个区域产业协会的枚举列表(或任意现有列表)为例,并根据使用修改模式组件。先前的模式提供 MaritalStatus 组件和值的枚举列表,如 清单 1 所示。
清单 1. 婚姻状况枚举列表
<xsd:simpleType name="MaritalStatusEnumType">
<xsd:restriction base="xsd:normalizedString">
<xsd:enumeration value="Divorced"/>
<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. 依赖关系枚举列表
上一页12 下一页 阅读全文
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
暂无评论...
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
2024年11月19日
2024年11月19日
- 好薇2024《兵哥哥》1:124K黄金母盘[WAV+CUE]
- 胡歌.2006-珍惜(EP)【步升大风】【FLAC分轨】
- 洪荣宏.2014-拼乎自己看【华特】【WAV+CUE】
- 伊能静.1999-从脆弱到勇敢1987-1996精选2CD【华纳】【WAV+CUE】
- 刘亮鹭《汽车DJ玩主》[WAV+CUE][1.1G]
- 张杰《最接近天堂的地方》天娱传媒[WAV+CUE][1.1G]
- 群星《2022年度发烧天碟》无损黑胶碟 2CD[WAV+CUE][1.4G]
- 罗文1983-罗文甄妮-射雕英雄传(纯银AMCD)[WAV+CUE]
- 群星《亚洲故事香港纯弦》雨果UPMAGCD2024[低速原抓WAV+CUE]
- 群星《经典咏流传》限量1:1母盘直刻[低速原抓WAV+CUE]
- 庾澄庆1993《老实情歌》福茂唱片[WAV+CUE][1G]
- 许巍《在别处》美卡首版[WAV+CUE][1G]
- 林子祥《单手拍掌》华纳香港版[WAV+CUE][1G]
- 郑秀文.1997-我们的主题曲【华纳】【WAV+CUE】
- 群星.2001-生命因爱动听电影原创音乐AVCD【MEDIA】【WAV+CUE】