首页 > 解决方案 > 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”在其选择器范围内匹配多个值;字段必须匹配

标签: xmlvalidationxsdconstraintsschema

解决方案


您还没有告诉我们 key/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])

推荐阅读