XSD 分层键结构
XSD Hierarchical key structure
我想在 'AxisConfiguration' 上为每个 MotionControl 设置一个复合键并在 '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>
验证结果:
Field "./AxisConfigurations/AxisConfiguration/@Axis" of identity constraint "PK_Axis" matches more than one value within the scope of its selector; fields must match
您没有告诉我们 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])
我想在 'AxisConfiguration' 上为每个 MotionControl 设置一个复合键并在 '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>
验证结果:
Field "./AxisConfigurations/AxisConfiguration/@Axis" of identity constraint "PK_Axis" matches more than one value within the scope of its selector; fields must match
您没有告诉我们 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])