使用 XSD 的 key/unique 和 keyref:您可以分别确保 @EnumName 值的属性与现有的 @enumName 匹配,并且 @EnumValueName 与 @valueName 匹配;给定当前的 EnumDefinition 结构(从面向对象的角度来看是有意义的),您不能同时实现两者。
我可以理解为什么——例如,程序员使用你的 XML 的可用性——你可以选择通过将它们复制到 EnumReference 的@EnumName 和@EnumValueName 中来复制(在数据库术语中非规范化)值。您可能需要考虑这对 XML 的性能和大小有负面影响;特别是如果您的 XML 中有很多 EnumReference ......
另一种非常符合关系模型的替代方法可能是简单地为每个 EnumDefinition 的 Value 元素添加一个标识属性,例如 @aid。您的 XML 将如下所示:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<root>
<EnumDefinitions>
<EnumDefinition enumName="MyEnum1">
<Values>
<Value aid="a" value="1" valueName="MyEnumValue1"/>
<Value aid="b" value="2" valueName="MyEnumValue2"/>
</Values>
</EnumDefinition>
<EnumDefinition enumName="MyEnum10">
<Values>
<Value aid="c" value="10" valueName="MyEnumValue10"/>
<Value aid="d" value="20" valueName="MyEnumValue20"/>
</Values>
</EnumDefinition>
</EnumDefinitions>
<EnumReference aid="a"/>
<EnumReference aid="f"/>
</root>
带有约束的 XSD 可以是:
<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="root">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="EnumDefinitions">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" name="EnumDefinition">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Values">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" name="Value">
<xsd:complexType>
<xsd:attributeGroup ref="aid"/>
<xsd:attribute name="value" type="xsd:unsignedByte" use="required"/>
<xsd:attribute name="valueName" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:key name="ValueUC">
<xsd:selector xpath="Value"/>
<xsd:field xpath="@value"/>
</xsd:key>
<xsd:key name="ValueNameUC">
<xsd:selector xpath="Value"/>
<xsd:field xpath="@valueName"/>
</xsd:key>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="enumName" type="xsd:string" use="required"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:key name="EnumNameUC">
<xsd:selector xpath="EnumDefinition"/>
<xsd:field xpath="@enumName"/>
</xsd:key>
</xsd:element>
<xsd:element maxOccurs="unbounded" name="EnumReference">
<xsd:complexType>
<xsd:attributeGroup ref="aid"/>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:key name="PK">
<xsd:selector xpath="EnumDefinitions/EnumDefinition/Values/Value"/>
<xsd:field xpath="@aid"/>
</xsd:key>
<xsd:keyref name="FK" refer="PK">
<xsd:selector xpath="EnumReference"/>
<xsd:field xpath="@aid"/>
</xsd:keyref>
</xsd:element>
<xsd:attributeGroup name="aid">
<xsd:attribute name="aid" type="xsd:string" use="required"/>
</xsd:attributeGroup>
</xsd:schema>
它看起来像这样:
它的意思是:
- 您的交叉参考在 PK/FK 约束方面存在
- UC 后缀约束确保您的完整性。
如果您无法对结构做任何事情,那么剩下的唯一选择是在 XSD 1.0 之上的 Schematron,或者迁移到 XSD 1.1 处理器(目前还没有普及,祝您好运,找到跨平台的优质免费处理器)。