xs:key和xs:keyref用于建立XSD中主键–外键式强一致性约束:key定义必存在、非空、全局唯一的标识,keyref校验引用值是否在key/unique的合法值集合中;二者须配合使用且作用域需重叠或嵌套。

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










