XSD分层密钥结构

问题描述

我想在每个MotionControl的“ AxisConfiguration”上设置一个复合键,并在“ PredefinedPositions”中引用它们。 每个MotionControl的Axis-Attribute必须唯一。 想法是在MotionControl的“ Id”和AxisConfiguration的“ Axis”上设置一个键。 但它不起作用,我现在也不知道如何实现。

<Root>
    <MotionControls>
        <MotionControl Id="1">
            <AxisConfigurations>
                <AxisConfiguration Axis="A0" MappedTo="X" Type="Linear" MaxVeLocity="0" Offset="0"/>
                <AxisConfiguration Axis="A1" MappedTo="Y" Type="Linear" MaxVeLocity="0" Offset="0"/>
            </AxisConfigurations>
        </MotionControl>
        <MotionControl Id="2">
            <AxisConfigurations>
                <AxisConfiguration Axis="A0" MappedTo="X" Type="Linear" MaxVeLocity="0" Offset="0"/>
                <AxisConfiguration Axis="A1" MappedTo="Y" Type="Linear" MaxVeLocity="0" Offset="0"/>
            </AxisConfigurations>
        </MotionControl>
    </MotionControls>
    <PredefinedPositions>
        <PredefinedPosition Name="PositionWorkingRoomHome" Order="Z,X,YA">
            <AxisPositions>
                <AxisPosition MotionControlId="1" Axis="A0" Value="1000"/>
                <AxisPosition MotionControlId="2" Axis="A0" Value="95000"/>
            </AxisPositions>
        </PredefinedPosition>
    </PredefinedPositions>
</Root>

 <xs:key name="PK_Axis">
  <xs:selector xpath=".//MotionControl"/>
  <xs:field xpath="@Id"/>
  <xs:field xpath="AxisConfigurations/AxisConfiguration/@Axis"/>
</xs:key>
<xs:keyref name="FK_Axis" refer="PK_Axis">
  <xs:selector xpath=".//AxisPosition"/>
  <xs:field xpath="@MotionControlId"/>
  <xs:field xpath="@Axis"/>
</xs:keyref>

验证结果:

身份约束“ PK_Axis”的字段“ ./AxisConfigurations/AxisConfiguration/@Axis”在其选择器范围内匹配多个值;字段必须匹配

解决方法

您尚未告诉我们键/ keyref约束在您的模式中出现的位置,这很关键。

但是话虽如此,我不确定这可以做到。当key和keyref出现在不同元素上时发生的事情的规则是如此复杂,以至于我不确定自己是对的,但我想不出一种解决方法。

使用XSD 1.1断言很容易,当然:在Root的声明中您可以断言

every $ap in .//AxisPosition satisfies 
  some $ac in .//AxisConfiguration satisfies 
    ($ap/@Axis = $ac/@Axis 
      and $ap/@MotionControlId = $ac/ancestor::MotionControl/@Id)

可能会提高一点效率,例如:

    every $ap in .//AxisPosition satisfies 
      exists(MotionControls/MotionControl[@Id = $ap/MotionControl 
        and AxisConfigurations/AxisConfiguration/@Axis = $ap/@MotionControlId])