【发布时间】:2018-06-02 16:45:23
【问题描述】:
many questions 介绍了当您可以按某个属性或值对这些元素进行分组时如何删除重复元素,但是,在我的情况下,这些属性已经在 XSLT 中动态生成,我不想拥有为每个元素编写每个属性以用作分组键。
如何在事先不知道其属性的情况下删除重复元素?到目前为止,我已经尝试在每个元素上使用 generate-id() 并按此进行分组,但问题是 generate-id 没有为具有相同属性的元素生成相同的 ID:
<xsl:template match="root">
<xsl:variable name="tempIds">
<xsl:for-each select="./*>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:attribute name="tempID">
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
<xsl:copy-of select="node()"/>
</xsl:copy>
</xsl:for-each>
</xsl:variable>
<xsl:for-each-group select="$tempIds" group-by="@tempID">
<xsl:sequence select="."/>
</xsl:for-each-group>
</xsl:template>
测试数据:
<root>
<child1>
<etc/>
</child1>
<dynamicElement1 a="2" b="3"/>
<dynamicElement2 c="3" d="4"/>
<dynamicElement2 c="3" d="5"/>
<dynamicElement1 a="2" b="3"/>
</root>
最终结果只是剩下的两个 dynamicElement1 元素之一:
<root>
<child1>
<etc/>
</child1>
<dynamicElement1 a="2" b="3"/>
<dynamicElement2 c="3" d="4"/>
<dynamicElement2 c="3" d="5"/>
</root>
【问题讨论】:
-
您使用哪种 XSLT 处理器?您想要测试数据的哪个结果?听起来好像带有
xsl:for-each-group select="*" composite="yes" group-by="@*"的XSLT 3 可能是一个选项。但我看不出一个元素如何拥有两个c属性,就像你的dynamicElement2元素一样。 -
@MartinHonnen 抱歉,这是一个错字。我的样式表使用 XSLT 2.0,但我可以在 3.0 中创建另一个样式表,如果这样更容易的话,它会链接到另一个样式表。我使用 SAXON EE 作为我的处理器
-
“问题是 generate-id 没有为具有相同属性的元素生成相同的 ID” 嗯,你从哪里得到的概念是案例?
-
嗯,
generate-id()的重点是生成唯一 ID,所以这不足为奇。 -
@Tomalak 我刚刚看到this 的回答。我误解并认为 generate-id 会为具有相似值和属性的节点返回相同的值,但我现在看到它也考虑了上下文。
标签: xslt xslt-2.0 saxon xslt-grouping exslt