如何用XSD验证XML中preDefinedRecipe的type必为recipeStructureDef的mnemonic值
解决方案:用XSD键与键引用实现跨元素属性约束
我来帮你搞定这个跨元素的属性匹配验证问题!要让<preDefinedRecipe>的type属性必须是<recipeStructureDef>的mnemonic属性值之一,你需要用到XSD中的**xs:key和xs:keyref**机制——这是XSD专门用来定义元素/属性之间引用关系的标准方法,完美解决你的需求。
核心思路
- 定义唯一键:先把所有
<recipeStructureDef>的mnemonic属性标记为合法的"键值集合",同时保证这些值唯一。 - 绑定键引用:让
<preDefinedRecipe>的type属性必须引用这个键值集合中的值,不匹配就验证失败。
完整XSD代码(整合你的现有代码)
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <!-- 定义parameterDef的类型 --> <xs:complexType name="preDefinedRecipeParameterDefType"> <xs:attribute name="ref" type="xs:string" use="required"/> <xs:attribute name="value" type="xs:string" use="required"/> </xs:complexType> <!-- 你已编写的preDefinedRecipeType --> <xs:complexType name="preDefinedRecipeType"> <xs:sequence> <xs:element type="preDefinedRecipeParameterDefType" name="parameterDef" maxOccurs="unbounded" minOccurs="0"/> </xs:sequence> <xs:attribute type="xs:string" name="type" use="required"/> <xs:attribute type="xs:string" name="name" use="required"/> <xs:attribute type="xs:byte" name="ordinal" use="required"/> <xs:attribute type="xs:string" name="writerLevel" use="required"/> </xs:complexType> <!-- 定义recipeStructureDef的类型 --> <xs:complexType name="recipeStructureDefType"> <xs:attribute name="mnemonic" type="xs:string" use="required"/> <xs:attribute name="title" type="xs:string" use="required"/> </xs:complexType> <!-- 根元素recipeConfig,核心约束定义在这里 --> <xs:element name="recipeConfig"> <xs:complexType> <xs:sequence> <xs:element name="recipeStructures"> <xs:complexType> <xs:sequence> <xs:element name="recipeStructureDef" type="recipeStructureDefType" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="preDefinedRecipes"> <xs:complexType> <xs:sequence> <xs:element name="preDefinedRecipe" type="preDefinedRecipeType" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> <!-- 1. 定义唯一键:所有recipeStructureDef的mnemonic是合法值且唯一 --> <xs:key name="validRecipeMnemonic"> <xs:selector xpath="recipeStructures/recipeStructureDef"/> <xs:field xpath="@mnemonic"/> </xs:key> <!-- 2. 定义键引用:preDefinedRecipe的type必须匹配上面的合法值 --> <xs:keyref name="recipeTypeReference" refer="validRecipeMnemonic"> <xs:selector xpath="preDefinedRecipes/preDefinedRecipe"/> <xs:field xpath="@type"/> </xs:keyref> </xs:element> </xs:schema>
关键部分解释
validRecipeMnemonic键:通过selector定位所有<recipeStructureDef>元素,用field指定mnemonic属性作为键值,自动保证这些值唯一,同时形成合法的type值集合。recipeTypeReference键引用:通过selector定位所有<preDefinedRecipe>元素,用field指定type属性,再通过refer关联到前面定义的键,强制type必须存在于合法值集合中。
测试验证
你的现有XML示例中,<preDefinedRecipe type="BREAD">是完全合法的,因为BREAD对应了一个<recipeStructureDef mnemonic="BREAD">。如果把type改成PIZZA(没有对应的mnemonic),XML验证会直接报错,完美符合你的需求。
内容的提问来源于stack exchange,提问作者madhu madi
相关产品推荐
相关产品推荐

