XML模式中的完整性约束

时间:2011-11-20 09:25:36

标签: xml xsd

我有这样的XML(工作流表示一种由进程实例化的类)。

<workflowManagementSystem>
    <workflows>
        <workflow name="workflow1">
            <actions>
                <action name="action1" role="role1"></action>
                <action name="action2" role="role3"></action>
                <action name="action3" role="role4"></action>
            </actions>
        </workflow>
        <workflow name="workflow2">
            <actions>
                <action name="action3" role="role4"></action>
                <action name="action2" role="role3"></action>
                <action name="action4" role="role4"></action>
            </actions>
        </workflow>
    </workflows>
    <actors>
        <actor name="actor1" role="role1"></actor>
        <actor name="actor2" role="role2"></actor>
        <actor name="actor3" role="role3"></actor>
        <actor name="actor4" role="role4"></actor>
        <actor name="actor5" role="role2"></actor>
    </actors>
    <processes>
        <process workflow="workflow1">
            <actionStatuses>
                <actionStatus action="action1" actor="actor1"></actionStatus>
                <actionStatus action="action2" actor="actor3"></actionStatus>
            </actionStatuses>
        </process>
        <process workflow="workflow1">
            <actionStatuses>
                <actionStatus action="action1" actor="actor1"></actionStatus>
                <actionStatus action="action2" actor="actor5"></actionStatus>
                <actionStatus action="action3" actor="actor4"></actionStatus>
            </actionStatuses>
        </process>
        <process workflow="workflow1">
            <actionStatuses>
                <actionStatus action="action2" actor="actor5"></actionStatus>
                <actionStatus action="action4" actor="actor4"></actionStatus>
            </actionStatuses>
        </process>
    </processes>
</workflowManagementSystem>

我想声明一些约束:

1)工作流程的名称必须是唯一的 2)动作的名称必须在包含它的工作流程范围内是唯一的 3)可以在流程中重复一个动作(更多actionStatus指的是相同的动作) 4)actionStatus应仅引用属于父进程实例化的特定工作流的动作 5)actionStatus中指示的actor必须属于与其引用的动作中指定的角色相同的角色。

有可能吗?

2 个答案:

答案 0 :(得分:1)

某些或您的要求可以,其他人无法使用XML Schema完成。

在进入细节之前,我还添加了一个额外的key / keyref(参照完整性),你没有要求,但我认为这对未来的参考可能有好处。 uniqueWorkflowInWorkflows就是您所要求的;我添加了pkWorkflow / fkProcessToWorkflow。 unique和key子句之间存在细微差别,但如果接受key / keyref,则不需要uniqueWorkflowInWorkflows。

这里值得一提的是,一般来说,如果你的设计允许使用xsd:unique子句,而不是xsd:key; xsd:keyref可以引用xsd:unique ...

答案是:

1)请参阅uniqueWorkflowInWorkflows或pkWorkflow

2)参见uniqueActionInWorkflow

3)这里没什么可做的。

4)无法在XML Schema中完成(直观地说,由于选择器支持的XPath语法的限制)。

5)无法在XML Schema中完成。

下面是根据俄罗斯玩偶创作风格从XML生成的XML Schema,这是唯一的“全局”声明是根元素的声明。

<?xml version="1.0" encoding="utf-8"?>
<!--W3C Schema generated by QTAssistant/W3C Schema Refactoring Module (http://www.paschidev.com)-->
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="workflowManagementSystem">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="workflows">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element maxOccurs="unbounded" name="workflow">
                                <xsd:complexType>
                                        <xsd:sequence>
                                            <xsd:element name="actions">
                                                <xsd:complexType>
                                                    <xsd:sequence>
                                                <xsd:element maxOccurs="unbounded" name="action">
                                                    <xsd:complexType>
                                                        <xsd:attribute name="name" type="xsd:string" use="required"/>
                                                        <xsd:attribute name="role" type="xsd:string" use="required"/>
                                                    </xsd:complexType>
                                                </xsd:element>
                                            </xsd:sequence>
                                        </xsd:complexType>
                                    </xsd:element>
                                </xsd:sequence>
                                <xsd:attribute name="name" type="xsd:string" use="required"/>
                            </xsd:complexType>
                            <xsd:unique name="uniqueActionInWorkflow">
                                <xsd:selector xpath="actions/action"/>
                                <xsd:field xpath="@name"/>
                            </xsd:unique>
                        </xsd:element>
                    </xsd:sequence>
                </xsd:complexType>
                <xsd:unique name="uniqueWorkflowInWorkflows">
                    <xsd:selector xpath="workflow"/>
                    <xsd:field xpath="@name"/>
                </xsd:unique>
            </xsd:element>
            <xsd:element name="actors">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element maxOccurs="unbounded" name="actor">
                            <xsd:complexType>
                                <xsd:attribute name="name" type="xsd:string" use="required"/>
                                <xsd:attribute name="role" type="xsd:string" use="required"/>
                            </xsd:complexType>
                        </xsd:element>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
            <xsd:element name="processes">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element maxOccurs="unbounded" name="process">
                            <xsd:complexType>
                                <xsd:sequence>
                                    <xsd:element name="actionStatuses">
                                        <xsd:complexType>
                                            <xsd:sequence>
                                                <xsd:element maxOccurs="unbounded" name="actionStatus">
                                                    <xsd:complexType>
                                                        <xsd:attribute name="action" type="xsd:string" use="required"/>
                                                        <xsd:attribute name="actor" type="xsd:string" use="required"/>
                                                    </xsd:complexType>
                                                </xsd:element>
                                            </xsd:sequence>
                                        </xsd:complexType>
                                    </xsd:element>
                                </xsd:sequence>
                                <xsd:attribute name="workflow" type="xsd:string" use="required"/>
                            </xsd:complexType>
                        </xsd:element>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
        </xsd:sequence>
    </xsd:complexType>
    <xsd:key name="pkWorkflow">
        <xsd:selector xpath="workflows/workflow"/>
        <xsd:field xpath="@name"/>
    </xsd:key>      
    <xsd:keyref name="fkProcessToWorkflow" refer="pkWorkflow">
        <xsd:selector xpath="processes/process"/>
        <xsd:field xpath="@workflow"/>
    </xsd:keyref>
</xsd:element>

这是XSD源的可视化:

XSD Visualization

答案 1 :(得分:0)

我已经认识到约束4和5不能在xml架构中翻译,但我已经解决了编辑架构结构并添加一些额外约束的其余问题。 XML:

<workflowManagementSystem xmlns="http://www.example.org/wfInfo"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.example.org/wfInfo wfInfo.xsd ">
    <workflows>
        <workflow name="wf1">
            <actions>
                <action name="ac1" role="role1">
                </action>
                <action name="ac2" role="role2">
                </action>
                <action name="ac3" role="AddettoVendite"
                    automaticallyInstantiated="true">
                    <nextAction actionName="ac1"></nextAction>
                    <nextAction actionName="ac2"></nextAction>
                </action>
            </actions>
            <processes>
                <process startTime="2011-10-13T12:30:00Z">
                    <actionStatuses>
                        <actionStatus action="ac1" actor="actor3"
                            terminationTime="2011-10-13T12:30:00Z"></actionStatus>
                        <actionStatus action="ac3" actor="actor2"></actionStatus>
                    </actionStatuses>
                </process>
                <process startTime="2011-10-13T12:30:00Z">
                    <actionStatuses>
                        <actionStatus action="ac1" actor="actor1"></actionStatus>
                    </actionStatuses>
                </process>
            </processes>
        </workflow>
        <workflow name="wf2">
            <actions>
                <action name="ac2" role="role2"
                    automaticallyInstantiated="true">
                    <nextAction actionName="ac4"></nextAction>
                </action>
                <action name="ac4" role="role2"
                    automaticallyInstantiated="false">
                    <nextAction actionName="ac2"></nextAction>
                </action>
                <action name="ac5" role="role1"
                    automaticallyInstantiated="false">
                </action>
            </actions>
            <processes>

            </processes>
        </workflow>
    </workflows>
    <actors>
        <actor name="Actor1">
            <roles>
                <role name="Role3"></role>
                <role name="Role4"></role>
            </roles>
        </actor>
        <actor name="Actor2">
            <roles>
                <role name="Role1"></role>
            </roles>
        </actor>
        <actor name="Actor3">
            <roles>
                <role name="Role1"></role>
                <role name="Role2"></role>
            </roles>
        </actor>
    </actors>
</workflowManagementSystem>

相应的架构是:

<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/wfInfo"
    xmlns:tns="http://www.example.org/wfInfo" elementFormDefault="qualified">

    <element name="workflowManagementSystem" type="tns:workflowManagementSystemType">

        <!-- CONSTRAINTS -->
        <key name="workflowKey">
            <selector xpath="tns:workflows/tns:workflow"></selector>
            <field xpath="@name"></field>
        </key>
        <keyref name="nextProcessRef" refer="tns:workflowKey">
            <selector
                xpath="tns:workflows/tns:workflow/tns:actions/tns:action/tns:nextProcess">
            </selector>
            <field xpath="@workflowName"></field>
        </keyref>

        <key name="actorKey">
            <selector xpath="tns:actors/tns:actor"></selector>
            <field xpath="@name"></field>
        </key>

        <keyref name="actorRef" refer="tns:actorKey">
            <selector
                xpath="tns:workflows/tns:workflow/tns:processes/tns:process/tns:actionStatuses/tns:actionStatus">
            </selector>
            <field xpath="@actor"></field>
        </keyref>

    </element>

    <!-- ROOT -->
    <complexType name="workflowManagementSystemType">
        <all>
            <!-- WORKFLOWS -->
            <element name="workflows" maxOccurs="1" minOccurs="1">
                <complexType>
                    <sequence>
                        <element name="workflow" type="tns:workflowType"
                            maxOccurs="unbounded" minOccurs="0">

                            <!-- CONSTRAINTS -->
                            <key name="actionKey">
                                <selector xpath="tns:actions/tns:action"></selector>
                                <field xpath="@name"></field>
                            </key>
                            <keyref name="nextActionRef" refer="tns:actionKey">
                                <selector xpath="tns:actions/tns:action/tns:nextAction"></selector>
                                <field xpath="@actionName"></field>
                            </keyref>
                            <keyref name="actionRef" refer="tns:actionKey">
                                <selector
                                    xpath="tns:processes/tns:process/tns:actionStatuses/tns:actionStatus"></selector>
                                <field xpath="@action"></field>
                            </keyref>
                        </element>
                    </sequence>
                </complexType>
            </element>

            <!-- ACTORS -->
            <element name="actors" maxOccurs="1" minOccurs="1">
                <complexType>
                    <sequence>
                        <element name="actor" type="tns:actorType" maxOccurs="unbounded"
                            minOccurs="0">

                        </element>
                    </sequence>
                </complexType>
            </element>
        </all>
    </complexType>

    <!-- WORKFLOW -->
    <complexType name="workflowType">
        <all>
            <!-- ACTIONS -->
            <element name="actions" maxOccurs="1" minOccurs="1">
                <complexType>
                    <sequence>
                        <element name="action" type="tns:actionType" maxOccurs="unbounded"
                            minOccurs="0"></element>
                    </sequence>
                </complexType>
            </element>
            <!-- PROCESSES -->
            <element name="processes" maxOccurs="1" minOccurs="1">
                <complexType>

                    <sequence>
                        <element name="process" type="tns:processType" maxOccurs="unbounded"
                            minOccurs="0">

                        </element>
                    </sequence>
                </complexType>
            </element>
        </all>
        <attribute name="name" type="string" use="required"></attribute>
    </complexType>

    <!-- PROCESS -->
    <complexType name="processType">
        <sequence>
            <!-- ACTIONSTATUSES -->
            <element name="actionStatuses" maxOccurs="1" minOccurs="1">
                <complexType>
                    <sequence>
                        <element name="actionStatus" type="tns:actionStatusType"
                            maxOccurs="unbounded" minOccurs="0">
                        </element>
                    </sequence>
                </complexType>

            </element>
        </sequence>
        <attribute name="startTime" type="dateTime" use="required"></attribute>
    </complexType>

    <!-- ACTION -->
    <complexType name="actionType">
        <choice>
            <element name="nextAction" maxOccurs="unbounded" minOccurs="0">
                <complexType>
                    <attribute name="actionName" type="string" use="required"></attribute>
                </complexType>
            </element>
            <element name="nextProcess" maxOccurs="1" minOccurs="1">
                <complexType>
                    <attribute name="workflowName" type="string" use="required"></attribute>
                </complexType>
            </element>
        </choice>
        <attribute name="name" type="string" use="required"></attribute>
        <attribute name="automaticallyInstantiated" type="boolean"
            use="required">
        </attribute>
        <attribute name="role" type="string" use="required"></attribute>
    </complexType>

    <!-- ACTIONSTATUS -->
    <complexType name="actionStatusType">
        <attribute name="action" type="string" use="required"></attribute>
        <attribute name="actor" type="string" use="optional"></attribute>
        <attribute name="terminationTime" type="dateTime" use="optional"></attribute>
    </complexType>

    <!-- ACTOR -->
    <complexType name="actorType">
        <sequence>
            <element name="roles" maxOccurs="1" minOccurs="1">
                <complexType>
                    <sequence>
                        <element name="role" type="tns:roleType" maxOccurs="unbounded"
                            minOccurs="1"></element>
                    </sequence>
                </complexType>
                <!-- CONSTRAINTS -->
                <unique name="actorRoleUnique">
                    <selector xpath="tns:role"></selector>
                    <field xpath="@name"></field>
                </unique>
            </element>
        </sequence>
        <attribute name="name" type="string" use="required"></attribute>
    </complexType>


    <complexType name="roleType">
        <attribute name="name" type="string" use="required"></attribute>
    </complexType>


</schema>