XSLT组/合并子项(使用密钥)

时间:2013-01-02 10:00:01

标签: xml xslt merge nodes xslt-grouping

我试图了解如何使用我已编写的代码推断出解决方案。

为了简化,我将首先解释我想做什么以及到目前为止所做的事情。

假设我在XSLT中有一个XML变量,其中包含几个具有相同title属性的节点。

使用@Dimitre Novatchev solution我已设法将它们合并为一个节点。

所以如果我有:

<t>
    <GroupData ID="xxx" Key="4" Temp="yyy">
        <ItemData ID="zzz" Value="3"/>
    </GroupData>
    <GroupData ID="yyy" Key="4" Temp="yyy">
        <ItemData ID="abc" Value="3"/>
    </GroupData>
    <GroupData ID="zzz" Temp="yyy">
        <ItemData ID="pqr" Value="1982"/>
    </GroupData>
    <GroupData ID="xxx" Key="4" Temp="yyy">
        <ItemData ID="www" Value="1982"/>
    </GroupData>
    <GroupData ID="yyy" Key="4" Temp="yyy">
        <ItemData ID="def" Value="1982"/>
    </GroupData>
    <GroupData ID="zzz" Temp="yyy">
        <ItemData ID="tuv" Value="1982"/>
    </GroupData>
</t>

使用以下密钥后

<xsl:key name="kGDByIdKey" match="GroupData" use="concat(@ID, '+', @Key)"/>

我会得到:

<t>
   <GroupData ID="xxx" Key="4" Temp="yyy">
      <ItemData ID="zzz" Value="3"/>
      <ItemData ID="www" Value="1982"/>
   </GroupData>
   <GroupData ID="yyy" Key="4" Temp="yyy">
      <ItemData ID="abc" Value="3"/>
      <ItemData ID="def" Value="1982"/>
   </GroupData>
   <GroupData ID="zzz" Temp="yyy">
      <ItemData ID="pqr" Value="1982"/>
      <ItemData ID="tuv" Value="1982"/>
   </GroupData>
</t>

现在我想稍微修改一下这个,我希望能够根据我的决定合并/合并标题。考虑到这一点,在上面的示例中,我想将xxx和zzz定义在同一组中,尽管它们使用的是不同的标题(极端情况 - 在我的工作区中我将它们定义为相同 - 我可能有更多的情况这一点)。

如果你能告诉我一般应该做什么的方向,我将不胜感激(我想我需要修改我的密钥或使用替代方法 - generate-id或其他方法)。

我发现自己只实施了需要大量不必要努力的糟糕解决方案。

1 个答案:

答案 0 :(得分:0)

我猜这是XSLT1这是一个耻辱,因为它在XSLT2中看起来更好但是无论如何你基本上需要确保你想要组合在一起的节点最终得到相同的密钥

<xsl:key name="kGDByIdKey" match="GroupData" use="concat(@ID, '+', @Key)"/>

只有具有相同的@ID和@key

才能获得相同的use属性

如果您将其更改为

<xsl:key name="kGDByIdKey" match="GroupData[not(@ID='xxx')]" use="concat(@ID, '+', @Key)"/>
<xsl:key name="kGDByIdKey" match="GroupData[@ID='xxx'] use="concat('zzz', '+', @Key)"/>

然后,ID xxx的节点将被编入索引(并因此分组)zzz(或者当您从节点构造查找值时需要进行类似的更改)

如果您正在使用xslt 2,您可以使用更简单的功能样式,在扩展到多个此类更改时可能不那么简单

<xsl:key name="kGDByIdKey" match="GroupData" use="concat(replace(@ID,'^xxx$','zzz'), '+', @Key)"/>