Ajouter de nouvelles valeurs à une liste est une exigence courante et nécessaire. Les modélistes souhaitent souvent intégrer dans une architecture système un moyen d'ajouter de la valeur ajoutée, et cette valeur ajoutée n'est pas connue lors de la phase de conception. Comment un concepteur de schéma peut-il créer une liste de valeurs d’énumération extensible et facile à mettre en œuvre ? Cet article présentera plusieurs façons d’atteindre cet objectif.
Les concepteurs de modèles et les implémenteurs ont besoin d’une extension
L'ajout de nouvelles valeurs à une liste est une exigence courante et nécessaire. Les concepteurs de modèles souhaitent souvent intégrer dans l'architecture du système un moyen d'ajouter de la valeur ajoutée, et cette valeur ajoutée n'est pas connue lors de la phase de conception. Comment un concepteur de schéma peut-il créer une liste extensible et facile à mettre en œuvre de valeurs énumérées ? Cet article présentera plusieurs façons d’atteindre cet objectif.
Les concepteurs et les implémenteurs de schémas ont besoin d'un moyen d'étendre les listes d'énumération existantes dans les schémas XML. Malheureusement, la spécification XML Schema ne permet pas l'expansion lors de la création de ces listes (voir Rubriques connexes). Les valeurs retenues lors de la phase de conception sont fixes et disponibles. Malgré cette limitation, les gens utilisent toujours diverses alternatives pour élargir leur liste. Ceci est souvent demandé par les clients utilisant des schémas existants qui ne peuvent pas être modifiés. Ils souhaitent maintenir la compatibilité ascendante tout en ajoutant de nouvelles fonctionnalités. Dans cet article, vous verrez comment les modélistes ont surmonté les obstacles pour obtenir cette fonctionnalité.
Une liste d'énumération est un ensemble spécifié de valeurs pour un point de données spécifique. Par exemple, vous pouvez afficher les codes de pays via une liste fixe de valeurs, notamment DE (Allemagne), US (États-Unis) et JP (Japon). Compte tenu d'un ensemble de valeurs donné, que faut-il faire lorsqu'un nouveau pays est identifié, tel que TL (Timor oriental) ou BA (Bosnie-Herzégovine) ? Les clients utilisant la liste de noms précédente doivent modifier leur implémentation pour s'adapter aux nouvelles valeurs.
Lors de l'utilisation d'un schéma XML pour modéliser des données, les valeurs d'énumération sont répertoriées explicitement. Par conséquent, la liste des codes de pays contient chaque valeur d’énumération dans l’ordre. Souvent, les nouvelles valeurs d'une liste doivent être identifiées et intégrées dans la liste, et les concepteurs de modèles tentent de trouver un moyen d'étendre la liste et, en fait, de l'intégrer dans la conception pour permettre l'ajout de nouvelles valeurs. dont la valeur ajoutée n'est pas connue au moment de la conception.
Créer une liste d'énumération extensible
Lors de la recherche d'une solution à ce problème, nous avons été influencés par quatre critères clés :
Tout d'abord, élargir la liste après la phase de conception. Qu'il s'agisse d'établir rapidement un nouveau partenaire commercial ou d'établir de nouveaux champs de données urgents, évoluer lorsque cela compte est un réel besoin.
Deuxièmement, être capable de valider les valeurs dans l'analyseur est essentiel pour simplifier la mise en œuvre.
Troisièmement, il est essentiel d'effectuer l'analyse et la vérification en un seul cycle. Cela évite de faire une validation dans un cycle et un analyseur séparés comme la solution Genericode. Pour certaines configurations, l’ajout de nouvelles exigences technologiques peut s’avérer trop coûteux ou trop long.
Enfin, la solution doit être rétrocompatible avec le schéma d'origine. Les modifications de liste incompatibles ne peuvent pas être appelées extensions.
Certaines personnes pensent que les listes de recensement ne devraient pas du tout être étendues. Les modélisateurs de données pourraient penser que s'ils souhaitent qu'un modèle inclue plus de données, en étendant le modèle, ils peuvent créer un schéma basé sur le produit, créant ainsi un modèle plus grand avec moins de contraintes lorsque cela est nécessaire. Si vous pouvez contrôler le schéma et le modèle de données d'origine, cela est possible, et cette approche peut être idéale. Cependant, si vous devez réellement évoluer après la phase de conception, une telle approche ne fonctionnera pas.
Il a également été avancé que la clé pour étendre la liste d'énumération est de ne pas utiliser d'analyseurs de validation de schéma XML. Genericode (voir Rubriques connexes) recommande de valider les listes d'énumération à un deuxième niveau, distinct du processus initial de validation de l'analyseur de schéma XML. Cette théorie est exacte et l’application de cette méthode deviendra de plus en plus répandue. Cependant, cette solution n’est pas possible si elle doit être complétée en un seul cycle d’analyse. Dans certains cas, il n'est pas possible d'effectuer un deuxième cycle de vérification.
Bien sûr, vous pouvez créer de nouveaux éléments dans une nouvelle liste. Cependant, il n’y a pas de compatibilité ascendante avec le mode brut. Notre objectif est d'obtenir une liste extensible tout en conservant une compatibilité ascendante (voir Ressources).
Pour les besoins de cet article, les hypothèses formulées ici sont basées sur mon expérience de travail avec des clients – à savoir la nécessité d'étendre une liste d'énumération existante avec une valeur ajoutée. De plus, je suppose que l'analyse et la validation du schéma XML se font en une seule étape.
Conditions nécessaires pour étendre la liste d'énumération
L'exemple d'extension comporte quatre conditions nécessaires :
Permet d'étendre la liste d'énumération après la phase de conception.
Vérifiez la liste d'énumération avec un analyseur.
Valider la liste d'énumération au sein d'un cycle.
Maintien de la compatibilité ascendante avec le mode original.
Par exemple, une équipe doit prendre une liste énumérée d'associations industrielles régionales (ou toute liste existante) et modifier les composants du schéma en fonction de leur utilisation. Le schéma précédent fournissait une liste énumérée de composants et de valeurs MaritalStatus, comme indiqué dans le listing 1.
Liste 1. Liste de recensement de l'état civil
<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"/>
Supposons qu'une entreprise souhaite utiliser ces valeurs et, en outre, encourage ses partenaires commerciaux importants à utiliser une autre valeur. L'Union civile est une valeur étendue dont l'entreprise reconnaît qu'elle ne fait pas partie du schéma initial. Mais sémantiquement parlant, il est également possible d'utiliser un élément existant — MaritalStatus —. Comment l’entreprise y parvient-elle ?
Retour en haut
Solution 1 : modifier le schéma d'origine pour inclure la nouvelle valeur d'énumération
Bien sûr, modifier le schéma d'origine pour inclure la nouvelle valeur d'énumération est l'approche la plus simple. Conservez des copies locales des schémas, puis modifiez les schémas pour prendre en charge les valeurs d'énumération utilisées par votre entreprise.
Avantages : Facile à mettre en œuvre
Inconvénients :
Nécessite l'édition des modèles originaux, qui changeront progressivement de manière incontrôlable. En cas d'extension d'une liste préexistante, le créateur (partenaire commercial, association, etc.) peut souhaiter publier une nouvelle version de la liste. Vous devez propager vos modifications à chaque nouvelle version. Le
Mode d'édition manuel peut provoquer des erreurs d'édition inattendues.
Si vous ne pouvez pas (ou ne voulez pas) modifier le motif original, vous aurez besoin d'une alternative.
Retour en haut
Solution 2 : Créer une nouvelle liste d'énumération et l'ajouter à la liste d'origine
La deuxième option consiste à créer une nouvelle liste d'énumération et à l'ajouter à la liste d'énumération d'origine. La liste 1 montre la liste originale de l'état civil. Le listing 2 montre la liste d'énumération nouvellement créée.
Listing 2. Nouvelle liste d'énumération de l'état civil
<xsd:simpleType name="MyExtMaritalStatusEnumType"> <xsd:restriction base="xsd:normalizedString"> <xsd:enumeration value="CivilUnion"/> </xsd:restriction> </xsd:simpleType>
Unionz-la avec la liste d'origine à l'aide de la balise
Listing 3. Combinaison de deux groupes de listes
<xsd:simpleType name="MaritalStatusType_Union"> <xsd:union memberTypes="MyExtMaritalStatusEnumType MaritalStatusEnumType"/> </xsd:simpleType> <xsd:element name="MaritalStatus" type="MaritalStatusType_Union"/>
Cette solution nécessite toujours de modifier le schéma, c'est-à-dire que l'élément MaritalStatus est représenté par MaritalStatusType Conversion de type en type MaritalStatusType_Union. Pas un grand changement, mais quand même un travail d'édition manuel.
Avantages : Ne modifie pas la liste d'énumération d'origine.
Inconvénients :
Toutes les valeurs doivent être connues lors de la phase de conception, évitant ainsi des solutions contraignantes tardives.
Nécessite la prise en charge de la balise
Retour en haut
Solution 3 : Créez un schéma et combinez-le avec le type enum primitif
Regardez maintenant le cas d'utilisation des données de population sur la couleur des yeux. Le listing 4 montre cette liste.
Listing 4. Liste d'énumération de la couleur des yeux de la personne
<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>
Ensuite, créez un motif (une expression régulière) qui prend la nouvelle valeur. Le modèle est n'importe quelle chaîne préfixée par x : . x : est un délimiteur entre une liste d’énumération standard et une liste étendue. Le listing 5 montre ce modèle.
Listing 5. Expression régulière pour l'expansion
<xsd:simpleType name="StringPatternType"> <xsd:restriction base="xsd:string"> <xsd:pattern value="x:\S.*"/> </xsd:restriction> </xsd:simpleType>
Enfin, combinez la liste avec le modèle à l'aide de la balise
Listing 6. Combinaison de liste d'énumération et de mode étendu
<xsd:simpleType name="MyExtPersonEyeColorType"> <xsd:union memberTypes="PersonEyeColorType StringPatternType"/> </xsd:simpleType> <xsd:element name="PersonEyeColor" type="MyExtPersonEyeColorType"/>
Le même nœud a des valeurs standard et étendues. Les deux valeurs sont facilement séparables et toutes deux peuvent être vérifiées à l'aide de l'analyseur, comme le montre le listing 7.
Listing 7. Exemple d'instance XML
<PersonEyeColor>Black</PersonEyeColor> <PersonEyeColor>x:Teal</PersonEyeColor>
Avantages :
Le même élément peut être utilisé pour toutes les données.
Validez les listes d'énumération de base avec des analyseurs.
Séparez clairement les valeurs d'extension.
Cette solution permet de lier de nouvelles valeurs ultérieurement.
Inconvénients :
Le contenu de l'élément doit être analysé pour déterminer s'il a été développé.
Les analyseurs de modèles doivent prendre en charge les expressions régulières.
Nécessite la prise en charge des balises
Retour en haut
Solution 4 : Utiliser des champs séparés pour les extensions
Dans cette solution, les champs d'énumération ne changent pas. Cependant, vous devrez concevoir un champ d'extension dans le schéma pour accueillir la valeur supplémentaire. Dans ce cas, la liste initiale est dépendante (rapport entre allocataire et personne à charge), comme le montre le Listing 8.
Listing 8. Liste d'énumération des dépendances
<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>
nécessite un attribut supplémentaire - extension - qui peut accueillir de nouvelles valeurs. Le listing 9 montre cette propriété.
Listing 9. L'attribut d'extension pour les dépendances
<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"/>
Le Listing 10 montre quelques exemples XML qui reflètent l'extension.
Listing 10. Exemple d'instance XML
<DependentRelationship>Child</DependentRelationship> <DependentRelationship extension="MyNewRelationship">Extension</DependentRelationship>
优点:
不需要编辑原始模式。
该解决方案允许在以后绑定新值。
在原始模式中显式设计 extension 方法。
缺点:
在设计阶段,必须在每个枚举列表中设计 extension 方法。
必须在元素中而不是在属性中设置枚举值。
回页首
解决方案 5: 基于文档的方法 —— 与字符串结合
注意:解决方案 5 和解决方案 6 违反了在一个周期内进行验证 这一要求。但是,我之所以在这里介绍它们,是因为在很多实际环境中可以使用这些方法。
在第 5 个解决方案中,使用
清单 11 显示通过
清单 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"/>
优点:可以添加任意的扩展值,即使在后期绑定时也可以添加。
缺点:
解析器不验证枚举值,在第二个步骤中才进行验证。
需要
回页首
解决方案 6: 基于文档的方法 —— 使用
要使用该方法,将实际的枚举值放到
清单 12. 在
<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 模式特性。
缺点:解析器不验证枚举值。
回页首
未讨论的方法
我省略了其他几种扩展枚举列表的解决方案。下面简单介绍了两种没有使用的方法:
使用
使用 substitutionGroup 元素替换包含所有值的联合列表: 另外一种出色的解决方案,使用了替换组和联合。将原始列表与新列表联合以创建一个完整的枚举列表,然后使用 substitutionGroups 标记(或
回页首
结束语
XML 模式设计者和实现人员需要一种方法来扩展现有的枚举列表。因为一旦原始列表创建后,规范不允许进行扩展,因此需要找到一种方法实际实现扩展。实现人员可以使用本文的示例来设计和扩展枚举列表。每种方法都有优缺点,没有一种方法在所有用例中都是最佳方法。那么,应该使用哪种方法呢?
请考虑这些经验法则:
如果您习惯编辑原始枚举列表或模式,而且在设计阶段就知道所有要扩展的枚举值,最好使用 解决方案 1(手动编辑原始列表)或 解决方案 2(创建新列表并加入到原始列表中)。
如果想使用相同的语义元素来包含基本枚举列表和扩展枚举列表,可以考虑 解决方案 3(与模式联合)。
如果允许原始列表与扩展列表有不同的字段,可以使用 解决方案 4(独立的字段)。
如果不想在解析器中解析枚举值,可以考虑 Genericode 方法或使用 解决方案 5 或 解决方案 6。
这些指导原则可以使模式设计者找到实用的最佳实践,而且可以帮助他们创建易于实现、可扩展的枚举列表。
XML 模式和 XML 实例示例 ExtendEnumeratedListsCode.zip 2KB
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!