【问题标题】:Integrity constraint in the XML schemaXML 模式中的完整性约束
【发布时间】:2011-11-22 05:11:18
【问题描述】:

我有一个这样的 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 中指示的参与者必须属于与其所指的操作中指定的角色相同的角色。

有可能吗?

【问题讨论】:

    标签: xml xsd


    【解决方案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 模式,遵循俄罗斯娃娃创作风格,即唯一的“全局”声明是根元素的声明。

    <?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 源的可视化:

    【讨论】:

    • 非常感谢,但我已经修改了模式以便与 JAXB 进行更灵活的交互。但是,哪个工具生成了这种可视化?
    • QTAssistant 自带的 XSD 编辑器。
    【解决方案2】:

    我已经认识到约束 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>
    

    【讨论】:

      猜你喜欢
      • 2021-08-03
      • 1970-01-01
      • 2012-01-31
      • 1970-01-01
      • 1970-01-01
      • 2012-07-11
      • 1970-01-01
      • 2015-04-11
      • 2020-01-14
      相关资源
      最近更新 更多