如何在RELAX NG中定义带枚举字符串的数据类型?
RELAX NG 枚举类型定义及XSD类型集成方案
一、RELAX NG中实现枚举的三种方式
1. 基于XSD数据类型的enumeration约束
直接利用你已引用的XSD数据类型库,通过<param>元素指定枚举值,逻辑和XSD的枚举规则完全对应:
<define name="DT.Unit"> <a:documentation>Data Type Unit: A fixed set of strings</a:documentation> <data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="normalizedString"> <param name="enumeration">Byte</param> <param name="enumeration">KiloByte</param> <param name="enumeration">MegaByte</param> <param name="enumeration">GigaByte</param> <param name="enumeration">TeraByte</param> </data> </define>
2. RELAX NG原生枚举方式(无需依赖XSD类型库)
用RELAX NG原生的<choice>+<value>组合,语法更直观,不需要引入XSD数据类型:
<define name="DT.Unit"> <a:documentation>Data Type Unit: A fixed set of strings</a:documentation> <choice> <value>Byte</value> <value>KiloByte</value> <value>MegaByte</value> <value>GigaByte</value> <value>TeraByte</value> </choice> </define>
3. 使用pattern正则约束
通过XSD的pattern facet,用正则表达式匹配所有允许的枚举值,适合简单场景:
<define name="DT.Unit"> <a:documentation>Data Type Unit: A fixed set of strings</a:documentation> <data datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" type="normalizedString"> <param name="pattern">Byte|KiloByte|MegaByte|GigaByte|TeraByte</param> </data> </define>
二、关于XSD定义在RELAX NG中的应用
RELAX NG通过datatypeLibrary属性引入XSD数据类型体系后,可通过<param>元素复用XSD的各种约束facet(比如enumeration、pattern、length等)。每个<param>的name对应XSD facet的名称,内容对应facet的取值,和XSD中的约束语法一一对应。
三、关于RELAX NG vs XSD的选择建议
如果已经完成了元素层级的搭建,RELAX NG在灵活性和可读性上更有优势,当前枚举场景完全可以用上述方案解决,无需急于切换到XSD。若后续需要深度兼容XSD生态、团队统一技术栈,再考虑迁移也不迟。
内容的提问来源于stack exchange,提问作者U. Windl
相关产品推荐
相关产品推荐

