作为我的原始帖子Group/merge childs of same nodes in xml/xslt的补充,我遇到了为不同节点重复多次该结构的问题(在层次结构中更高的节点),例如,
<Collection>
<Questionnaire Name="Preferences" VersionID="3QW">
<Subject ID="2355">
<EventData Name="First Part">
<FormData Name="Past">
<GroupData ID="xxx" Key="4" Temp="yyy">
<ItemData ID="zzz" Value="3"/>
</GroupData>
<GroupData ID="xxx" Key="4" Temp="yyy">
<ItemData ID="qqq" Value="4"/>
</GroupData>
...
</FormData>
<FormData Name="Present">
<GroupData ID="yyy" Key="9" Temp="yyy">
<ItemData ID="www" Value="32"/>
</GroupData>
...
</FormData>
</EventData>
<EventData Name="SecondPart">
...
</EventData>
</Subject>
<Subject ID="9812">
...
</Subject>
</Questionnaire>
</Collection>
尝试了我所接受的建议的变化以及其他一些我被困住的事情。我认为它与多个级别有关(并且GroupData分布在它将成为子节点的上/祖父节点上)然后它可能不再具有唯一ID。那么如何将每个GroupData节点的子节点放入一个GroupData节点(在ID上匹配,有时是Key,因为后者并不总是存在)?注意:必须将相同的GroupData节点(具有相应的属性)合并到每个FormData节点中的一个GroupData节点中。
答案 0 :(得分:0)
以下是两个XSLT 1.0解决方案。
一个解决方案是从第一个问题中获取Dimite的解决方案,然后展开密钥以包含FormData ...
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kGDByIdKey" match="FormData/GroupData"
use="concat(@ID, '+', @Key, '+', generate-id(..))"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"FormData/GroupData
[generate-id()
=
generate-id(key('kGDByIdKey', concat(@ID, '+', @Key, '+', generate-id(..)))[1])
]">
<xsl:copy>
<xsl:apply-templates select=
"@*|key('kGDByIdKey', concat(@ID, '+', @Key, '+', generate-id(..)))/node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="GroupData"/>
</xsl:stylesheet>
另一个解决方案将分组测试从模板匹配条件移动到父FormData中调用xsl:apply-templates ...
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kGDByIdKey" match="FormData/GroupData" use="concat(@ID, '+', @Key)" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="FormData">
<xsl:copy>
<xsl:apply-templates select="
@* |
node()[not(self::GroupData)] |
GroupData[generate-id() =
generate-id(key('kGDByIdKey', concat(@ID, '+', @Key))[1])]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="FormData/GroupData">
<xsl:copy>
<xsl:apply-templates select="@*|
key('kGDByIdKey', concat(@ID, '+', @Key))/node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="GroupData"/>
</xsl:stylesheet>
两个样式表都假设GroupData的父级只是FormData。任何没有FormData父级的GroupData都将被删除。