我有元素连接器,它有源和目标。但是源有时可能是一个元素,有时是另一个元素(初始节点或活动)。所以我有两把钥匙。我想用一把钥匙或另一把钥匙。我的XML输入示例:
<packagedElement>
<node xmi:type="uml:InitialNode" xmi:id="EAID_a" name="ActivityInitial">
<outgoing xmi:idref="EAID_A7A0C176_5CCC_4bf2_AED2_AEB05FB741AF"/>
</node>
<group xmi:type="uml:ActivityPartition" xmi:id="EAID_b" name="Partition_1">
<node xmi:idref="EAID_c"/>
</group>
<packagedElement xmi:type="uml:Activity" xmi:id="EAID_c" name="Activity1"/>
<group xmi:type="uml:ActivityPartition" xmi:id="EAID_d" name="Partition_2">
<node xmi:idref="EAID_e"/>
</group>
<packagedElement xmi:type="uml:Activity" xmi:id="EAID_e" name="Activity2"/>
</packagedElement>
...
<connector xmi:idref="EAID_A7A0C176_f">
<source xmi:idref="EAID_a"/>
<target xmi:idref="EAID_c"/>
</connector>
<connector xmi:idref="EAID_CEB43B7F_g"/>
<source xmi:idref="EAID_c"/>
<target xmi:idref="EAID_e"/>
</connector>
这是我的XSLT:
<xsl:key name="grp" match="group" use="node/@xmi:idref" />
<xsl:key name="ini" match="*[@xmi:type='uml:InitialNode']" use="@xmi:id" />
...
<connector xmi:idref="EAID_CONNECTR{substring(@xmi:id, 14, 28)}">
<source xmi:idref="(EAID_LIFELINE{key('grp', @source)/substring(@xmi:id, 14, 28)})({key('ini', @source)/@xmi:id})"/>
<target xmi:idref="EAID_LIFELINE{key('grp', @target)/substring(@xmi:id, 14, 28)}"/>
</connector>
对于两个连接器,WRONG xml输出看起来像这样:
<connector xmi:idref="EAID_CONNECTR_f">
<source xmi:idref="(EAID_LIFELINE)(EAID_a)"/>
<target xmi:idref="EAID_LIFELINE_c"/>
</connector>
<connector xmi:idref="EAID_CONNECTR_g">
<source xmi:idref="(EAID_LIFELINE_c)()"/>
<target xmi:idref="EAID_LIFELINE_e"/>
</connector>
但XML输出应该如下所示:
<connector xmi:idref="EAID_CONNECTR_5CCC_4bf2_AED2_AEB05FB741AF">
<source xmi:idref="EAID_a"/>
<target xmi:idref="EAID_LIFELINE_c"/>
</connector>
<connector xmi:idref="EAID_CONNECTR_ED15_4f03_8D9B_8EF054BD458D">
<source xmi:idref="EAID_LIFELINE_c"/>
<target xmi:idref="EAID_LIFELINE_e"/>
</connector>
因此,如果我使用密钥“grp”,则应该有前缀EAID_LIFELINE,但如果我使用密钥“ini”,则应该具有所有不带前缀的id。如何根据我的需要编辑XSLT?
我可以理解当前的XSLT如何与您的XML和期望的输出相对应,部分原因是您的XSLT正在寻找@source
属性,这在XML中不存在。
但总的来说,如果您确实使用的是XSLT 2.0,那么这可能是if ... else ...
构造的一种情况,因此您可以像这样编写表达式:
<source xmi:idref="{
if (key('grp', @source))
then concat('EAID_LIFELINE', key('grp', @source)/substring(@xmi:id, 14, 28))
else key('ini', @source)/@xmi:id
}"/>
还要注意,使用“ini”键令人困惑......
key('ini', @source)/@xmi:id
因为“ini”键具有@xmi:id
的“use”属性,所以如果@source
等于@xmi:id
元素上的node
,则键只会返回任何内容。换句话说,key('ini', @source)/@xmi:id
等于@source
。