xs:key和xs:keyref用于建立XSD中主键–外键式强一致性约束:key定义必存在、非空、全局唯一的标识,keyref校验引用值是否在key/unique的合法值集合中;二者须配合使用且作用域需重叠或嵌套。
在XSD中,xs:key和xs:keyref是用来建立强一致性约束的核心机制,本质是模拟数据库的“主键–外键”关系。它们必须配合使用,不能单独存在;key定义谁是“被引用的唯一标识”,keyref定义谁“引用了它”,且二者作用域需重叠或嵌套。
xs:key要求指定字段**必须存在、非空、全局唯一**(在它的作用域内)。它由三部分组成:
keyref的refer属性引用xpath="book")xpath="@isbn"或xpath="title
")例如,确保每本book的isbn属性不为空且全文档唯一:
xs:keyref本身不保证唯一性,只校验“所填的值是否在某个key或unique定义的合法值集合中”。它也必须包含name、xs:selector和xs:field,外加一个关键属性:
xs:key或xs:unique的name
例如,定义order中的book_isbn必须引用已有book的isbn:
注意:order/book_isbn文本内容必须等于某本book/@isbn的值,否则XML验证失败。
二者结构相同,但语义不同:
xs:key:字段值必须存在且非空,适合做主键(如ID、ISBN)xs:unique:字段值可为空或缺失,缺失时跳过校验,适合宽松唯一场景(如可选的邮箱、备用编号)xs:keyref只能引用xs:key或xs:unique,不能引用另一个keyref
若你允许某字段为空但一旦有值就必须唯一,用unique;若该字段是核心标识、绝不允许缺省,就用key。
实际编写时容易出错的地方:
xs:selector的XPath必须匹配到元素,不能写错层级(比如xpath="books/book" vs xpath="book")xs:field路径必须返回单个原子值;写成xpath="author/name"可能返回多个节点,导致验证异常key和keyref必须定义在同一个xs:element或xs:schema范围内,跨复杂类型需注意作用域嵌套key对应元素根本不存在,整个key约束失效(不会报错),所以确保数据结构覆盖完整