2

I have a structure like this:

<EnumDefinitions>
    <EnumDefinition enumName="MyEnum1">
        <Values>
            <Value value="1" valueName="MyEnumValue1"/>
            <Value value="2" valueName="MyEnumValue2"/>
        </Values>
    </EnumDefinition>
    <EnumDefinition enumName="MyEnum10">
        <Values>
            <Value value="10" valueName="MyEnumValue10"/>
            <Value value="20" valueName="MyEnumValue20"/>
        </Values>
    </EnumDefinition>
</EnumDefinitions>
<EnumReference EnumName="MyEnum1" EnumValueName="MyEnumValue0"/>
<EnumReference EnumName="MyEnum1" EnumValueName="MyEnumValue10"/>

I want that the first EnumReference is valid but the second one should fail. For that I tried this unique and keyref:

    <xs:keyref name="keyref_EnumNameValue" refer="unique_EnumNameValuePair">
        <xs:selector xpath="EnumReference"/>
        <xs:field xpath="@EnumName"/>
        <xs:field xpath="@EnumValueName"/>
    </xs:keyref>
    <xs:unique name="unique_EnumNameValuePair">
        <xs:selector xpath="EnumDefinitions/EnumDefinition"/>
        <xs:field xpath="@enumName"/>
        <xs:field xpath="Values/Value/@valueName"/>
    </xs:unique>

but then I receive an error by validating:
Field '{anonymous}' of identity constraint 'unique_EnumNameValuePair' evaluates to a node-set with more than one member.

Is there a possibility to do this?

4

1 回答 1

2

使用 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 处理器(目前还没有普及,祝您好运,找到跨平台的优质免费处理器)。

于 2013-09-26T13:31:29.183 回答