如果我有一个元素,动物:
<animal name="dog"/>
可以将以下值作为name属性的值:
其中$(ANY_STRING)是一个简单的名称,某些软件将执行并稍后验证的值替换(ANY_STRING实际上是任何字符串)。这个元素的XML Schema是什么样的?限制三个已知名称很容易:
<xs:simpleType name="AnimalNames">
<xs:restriction base="xs:string">
<xs:enumeration value="dog"/>
<xs:enumeration value="cat"/>
<xs:enumeration value="bird"/>
</xs:restriction>
</xs:simpleType>
限制$(ANY_STRING)同样容易(使用xs:pattern to restrict)。但由于属性可能只是简单类型,是否可以指定属性可能在枚举列表或$(ANY_STRING)值中?
我考虑的另一个选择是限制以下模式:
<xs:pattern value="dog|cat|bird|$(.*)"/>
虽然随着可能值列表的增加而变得非常讨厌。
当然,最简单的选择就是声明一个字符串类型,但我希望比这更具限制性。
答案 0 :(得分:0)
定义这样的半封闭列表的一种方法是,为文档明确指定一组众所周知的值,然后使用escape-hatch来允许其他字符串,是使用union的union来定义属性。您的AnimalNames
类型和xs:NMTOKEN或xs:名称(或任何内置或用户定义的类型最好捕获您对未枚举的其他名称的约束)。
正如guidot在评论中指出的那样,这样的联盟接受与其最具包容性的成员类型相同的价值观,因此对于其唯一目的是守门的模式而言,这是毫无意义的。该技术对于文档和类型驱动的调度很有用(如果验证成员类型为AnimalNames
,则X执行Y)。
为了容纳模式验证器,这些模式验证器不提供有关哪种成员类型验证了联合类型的特定值的信息,一些词汇设计者会像guidot建议的那样做,并提供两种元素类型,一种用于已知/预测/预期的动物名称和其他名称。或者他们将类型AnimalNames
指定为接受字符串dog
,cat
,bird
和other
,将属性name
定义为具有类型AnimalNames
,并定义另一个属性(称为other-name
),当{且仅当name="other"
时,该属性被定义为具有含义。所以狗是用
<animal name="dog"/>
与仓鼠
<animal name="other" other-name="hamster"/>
这使得处理众所周知的名字变得相当简单,同时仍然接受其他名称。