我有一个xml文档:
<bans>
<ban job="gh:test/test#1">
<login>user1</login>
<reason>reason one</reason>
</ban>
<ban job="gh:test/test#1">
<login>user1</login>
<reason>reason two</reason>
</ban>
<ban job="gh:test/test#1">
<login>user2</login>
<reason>reason three</reason>
</ban>
<ban job="gh:test/test#2">
<login>user1</login>
<reason>reason four</reason>
</ban>
<ban job="gh:test/test#1">
<login>user2</login>
<reason>reason five</reason>
</ban>
</bans>
如何与ban
属性和job
值相同的所有login
元素合并xslt并从最新选择reason
值?
在这个示例中,我想首先合并第二个ban
元素,因为它们都有job="gh:test/test#1"
和<login>user1</login>
,第三个是第五个,所以转换的结果应该是这样的:
<bans>
<ban job="gh:test/test#1">
<login>user1</login>
<reason>reason two</reason>
</ban>
<ban job="gh:test/test#2">
<login>user1</login>
<reason>reason four</reason>
</ban>
<ban job="gh:test/test#1">
<login>user2</login>
<reason>reason five</reason>
</ban>
</bans>
答案 0 :(得分:2)
使用XSLT 3,您可以使用<xsl:for-each-group select="ban" group-by="@job, login" composite="yes">
:
如果存在
group-by
或group-adjacent
属性,则对于群体中的每个项目,计算一组分组键,如下所示:包含的表达式在group-by
或group-adjacent
属性中评估;结果是雾化的;并且任何xs:untypedAtomic
值都会转换为xs:string
。如果指定了
composite="yes"
,则只有一个分组键,其值为结果序列;否则,有一组分组键,由结果序列中存在的不同原子值组成。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="bans">
<xsl:copy>
<xsl:for-each-group select="ban" composite="yes" group-by="@job, login">
<xsl:copy-of select="current-group()[last()]"/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>