목록에 새 값을 추가하는 것은 일반적이고 필요한 요구 사항입니다. 패턴 디자이너는 종종 부가가치를 추가하는 방법으로 시스템 아키텍처를 구축하고 싶어하는데, 그 부가가치는 디자인 단계에서는 알 수 없습니다. 스키마 디자이너는 확장 가능하고 구현하기 쉬운 열거 값 목록을 어떻게 만들 수 있습니까? 이 기사에서는 이 목표를 달성하는 여러 가지 방법을 소개합니다.
패턴 디자이너와 구현자에게는 확장이 필요합니다.
목록에 새로운 값을 추가하는 것은 일반적이고 필요한 요구 사항입니다. 패턴 디자이너는 종종 부가 가치를 추가하는 방식으로 시스템 아키텍처를 구축하기를 원하며, 그 부가 가치는 디자인 단계에서는 알려지지 않습니다. 스키마 디자이너는 확장 가능하고 구현하기 쉬운 열거 값 목록을 어떻게 만들 수 있나요? 이 기사에서는 이 목표를 달성하는 여러 가지 방법을 소개합니다.
스키마 설계자와 구현자는 XML 스키마의 기존 열거 목록을 확장할 수 있는 방법이 필요합니다. 안타깝게도 XML 스키마 사양에서는 이러한 목록을 생성하는 동안 확장을 허용하지 않습니다(참고자료 참조). 설계 단계에서 선택된 값은 고정되어 사용 가능합니다. 이러한 제한에도 불구하고 사람들은 목록 확장을 위해 여전히 다양한 대안을 사용합니다. 이는 변경할 수 없는 기존 스키마를 사용하는 고객이 요청하는 경우가 많습니다. 그들은 새로운 기능을 추가하면서 이전 버전과의 호환성을 유지하기를 원합니다. 이 기사에서는 패턴 디자이너가 이 기능을 달성하기 위해 장애물을 어떻게 극복했는지 살펴보겠습니다.
열거 목록은 특정 데이터 요소에 대해 지정된 값 집합입니다. 예를 들어 DE(독일), US(미국) 및 JP(일본)를 포함하여 고정된 값 목록을 통해 국가 코드를 볼 수 있습니다. 주어진 값 집합이 주어지면 TL(동티모르) 또는 BA(보스니아 헤르체고비나)와 같은 새로운 국가가 식별되면 어떻게 해야 합니까? 이전 이름 목록을 사용하는 클라이언트는 새 값을 수용하도록 구현을 변경해야 합니다.
XML 스키마를 사용하여 데이터를 모델링하는 경우 열거형 값이 명시적으로 나열됩니다. 따라서 국가 코드 목록에는 각 열거 값이 순서대로 포함됩니다. 종종 목록의 새로운 값을 식별하고 목록에 수용해야 하며, 패턴 디자이너는 목록을 확장하는 방법을 찾으려고 노력하고 결과적으로 이를 디자인에 구축하여 새로운 값을 추가할 수 있습니다. 디자인 타임에는 알려지지 않은 부가 가치입니다.
확장 가능한 열거 목록 만들기
이 문제에 대한 해결책을 찾을 때 우리는 네 가지 주요 기준에 영향을 받았습니다.
먼저, 디자인 단계 후에 목록을 확장합니다. 새로운 거래 파트너를 신속하게 구축하든, 시간이 중요한 새로운 데이터 필드를 구축하든, 중요한 순간에 확장하는 것이 실제로 필요합니다.
두 번째로, 구현을 단순화하려면 파서에서 값의 유효성을 검사할 수 있는 것이 중요합니다.
셋째, 한 번의 주기로 구문 분석과 검증을 완료하는 것이 중요합니다. 이렇게 하면 Genericode 솔루션과 같은 별도의 주기 및 파서에서 유효성 검사를 수행하지 않아도 됩니다. 일부 설정의 경우 새로운 기술 요구 사항을 추가하는 데 비용이 많이 들거나 시간이 많이 걸릴 수 있습니다.
마지막으로 솔루션은 원래 스키마와 역호환되어야 합니다. 호환되지 않는 목록 변경 사항은 확장이라고 부를 수 없습니다.
어떤 사람들은 열거 목록을 전혀 확장하면 안 된다고 생각합니다. 데이터 모델러는 모델에 더 많은 데이터가 포함되도록 만들고 모델을 확장하면 제품을 기반으로 스키마를 생성할 수 있다고 생각할 수 있습니다. 즉, 필요할 때 더 적은 제약 조건으로 더 큰 모델을 생성할 수 있습니다. 원래 스키마와 데이터 모델을 제어할 수 있다면 그렇게 하는 것이 가능하며 이 접근 방식이 이상적일 수 있습니다. 그러나 설계 단계 이후에 실제로 확장해야 하는 경우 이러한 접근 방식은 작동하지 않습니다.
열거 목록 확장의 핵심은 XML 스키마 유효성 검사 파서를 사용하지 않는 것이라고 생각하는 사람들도 있습니다. Genericode(참고자료 참조)는 초기 XML 스키마 구문 분석기 유효성 검사 프로세스와 별도로 두 번째 수준에서 열거 목록의 유효성을 검사할 것을 권장합니다. 이 이론은 정확하며 이 방법의 적용은 점점 더 널리 퍼질 것입니다. 그러나 이 솔루션은 하나의 구문 분석 주기 내에 완료되어야 하는 경우에는 불가능합니다. 경우에 따라 두 번째 검증 주기를 수행할 수 없습니다.
물론 새 목록에 새 요소를 만들 수도 있습니다. 그러나 원시 모드에는 이전 버전과의 호환성이 없습니다. 우리의 목표는 이전 버전과의 호환성을 유지하면서 확장 가능한 목록을 얻는 것입니다(참고자료 참조).
이 기사의 목적상 여기에 제시된 가정은 고객과 함께 일한 경험, 즉 부가 가치를 추가하여 기존 열거 목록을 확장해야 한다는 필요성을 바탕으로 한 것입니다. 또한 XML 스키마 구문 분석 및 유효성 검사가 한 단계로 수행된다고 가정합니다.
열거 목록 확장에 필요한 조건
확장 예제에는 네 가지 필수 조건이 있습니다.
설계 단계 후에 열거 목록을 확장할 수 있습니다.
파서로 열거 목록을 확인합니다.
주기 내에서 열거 목록의 유효성을 검사합니다.
원래 모드와의 하위 호환성을 유지합니다.
예를 들어 팀은 지역 산업 협회의 열거 목록(또는 기존 목록)을 가져와 용도에 따라 스키마 구성 요소를 수정해야 합니다. 이전 스키마는 목록 1에 표시된 대로 MaritalStatus 구성 요소 및 값의 열거 목록을 제공했습니다.
목록 1. 혼인 여부 열거 목록
<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>
목록 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 유형으로 변환을 입력하세요. 큰 변화는 아니지만 여전히 일부 수동 편집 작업이 있습니다.
장점: 원래 열거 목록을 변경하지 않습니다.
단점:
모든 값은 설계 단계에서 알려져야 하므로 지연 바인딩 솔루션을 방지할 수 있습니다.
맨 위로
해결책 3: 스키마를 생성하고 이를 기본 열거형과 결합합니다.
이제 눈 색깔에 대한 인구 데이터 사용 사례를 살펴보겠습니다. Listing 4는 이 목록을 보여준다.
목록 4. 사람 눈 색깔 열거 목록
<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>
마지막으로 목록 6과 같이
목록 6. 열거 목록과 확장 모드의 조합
<xsd:simpleType name="MyExtPersonEyeColorType"> <xsd:union memberTypes="PersonEyeColorType StringPatternType"/> </xsd:simpleType> <xsd:element name="PersonEyeColor" type="MyExtPersonEyeColorType"/>
동일한 노드에는 표준 값과 확장 값이 있습니다. 두 값은 쉽게 분리할 수 있으며 둘 다 Listing 7에 표시된 대로 파서를 사용하여 확인할 수 있습니다.
목록 7. 샘플 XML 인스턴스
<PersonEyeColor>Black</PersonEyeColor> <PersonEyeColor>x:Teal</PersonEyeColor>
장점:
모든 데이터에 동일한 요소를 사용할 수 있습니다.
파서를 사용하여 기본 열거 목록의 유효성을 검사합니다.
확장자 값을 명확하게 구분하세요.
이 솔루션을 사용하면 나중에 새로운 값을 바인딩할 수 있습니다.
단점:
확장 여부를 확인하려면 요소의 콘텐츠를 구문 분석해야 합니다.
패턴 파서는 정규식을 지원해야 합니다.
맨 위로
해결책 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>
에는 새로운 값을 수용할 수 있는 추가 속성 (확장)이 필요합니다. 목록 9에서는 이 속성을 보여줍니다.
목록 9. 종속성을 위한 확장 속성
<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은 확장을 반영하는 몇 가지 XML 예를 보여줍니다.
목록 10. 샘플 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
위 내용은 XML 스키마의 열거 목록 확장을 위한 샘플 코드에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!