如何用XSD验证XML中department的director属性匹配员工护照号?
实现XML中部门主管与员工护照号的XSD验证
要确保department的director属性值与该部门下某一employee的PassportNumber属性匹配,可根据你使用的XSD版本选择以下方案:
XSD 1.1 方案(推荐,逻辑更直观)
XSD 1.1支持断言(xs:assert),可以直接在department的类型定义中添加约束,检查当前部门下是否存在符合条件的员工。
完整XSD代码:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1"> <xs:element name="company"> <xs:complexType> <xs:sequence> <xs:element name="departments"> <xs:complexType> <xs:sequence> <xs:element name="department" maxOccurs="unbounded"> <xs:complexType> <xs:sequence> <xs:element name="employee" maxOccurs="unbounded"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="lastname" type="xs:string"/> <xs:element name="salary" type="xs:decimal"/> </xs:sequence> <xs:attribute name="PassportNumber" type="xs:string" use="required"/> </xs:complexType> </xs:element> </xs:sequence> <xs:attribute name="IDDepartment" type="xs:string" use="required"/> <xs:attribute name="director" type="xs:string" use="required"/> <!-- 核心断言:检查当前部门存在员工的PassportNumber等于director --> <xs:assert test="some $emp in employee satisfies $emp/@PassportNumber = @director"/> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
关键说明
vc:minVersion="1.1"声明使用XSD 1.1版本<xs:assert>标签中的test表达式:some $emp in employee satisfies $emp/@PassportNumber = @director,意思是当前部门下至少存在一个员工,其PassportNumber属性值等于该部门的director属性值
XSD 1.0 方案(兼容旧版解析器)
XSD 1.0不支持断言,需通过xs:key和xs:keyref来实现关联约束,核心是将部门内员工的PassportNumber定义为唯一键,再让director引用这个键。
完整XSD代码:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="company"> <xs:complexType> <xs:sequence> <xs:element name="departments"> <xs:complexType> <xs:sequence> <xs:element name="department" maxOccurs="unbounded"> <xs:complexType> <xs:sequence> <xs:element name="employee" maxOccurs="unbounded"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element name="lastname" type="xs:string"/> <xs:element name="salary" type="xs:decimal"/> </xs:sequence> <xs:attribute name="PassportNumber" type="xs:string" use="required"/> </xs:complexType> </xs:element> </xs:sequence> <xs:attribute name="IDDepartment" type="xs:string" use="required"/> <xs:attribute name="director" type="xs:string" use="required"/> </xs:complexType> <!-- 定义部门内员工PassportNumber为唯一键 --> <xs:key name="empPassportKey"> <xs:selector xpath="employee"/> <xs:field xpath="@PassportNumber"/> </xs:key> <!-- 让director引用该键 --> <xs:keyref name="directorRef" refer="empPassportKey"> <xs:selector xpath="."/> <xs:field xpath="@director"/> </xs:keyref> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
关键说明
<xs:key>:在每个department节点范围内,employee的PassportNumber是唯一标识(确保部门内员工护照号不重复)<xs:keyref>:指定department的director属性必须引用同一部门内某个employee的PassportNumber属性值
验证效果
用你提供的XML测试两种XSD:
- 符合要求的XML会通过验证
- 如果修改
department的director为该部门不存在的护照号(比如把A01部门的director改成99999999X),验证会报错,提示约束不满足
内容的提问来源于stack exchange,提问作者Cryptter
相关产品推荐
相关产品推荐

