我有一个包含以下标记的xml文件
<xml>
<content relationship="regula">
**<source attribute1="RSC1985s5c1" attribute2="6(17)"/>**
<target attribute1="LRC1985s5c1" attribute1="6(17)1"/>
</content>
<content relationship="translation-of">
**<source attribute1="RSC1985s5c1" attribute2="6(17)"/>**
<target attribute1="LRC1985s5c4" attribute2="6(17)1"/>
</content>
<content relationship="translation-of">
**<source attribute1="RSC1985s5c2" attribute2="7(17)"/>**
<target attribute1="LRC1985s5c2" attribute2="7(17)"/>
</content>
<content relationship="translation-of">
**<source attribute1="RSC1985s5c1" attribute2="6(17)"/>**
<target attribute1="LRC1985s5c6" attribute2="6(17)2"/>
</content>
</xml>
如果源节点的attribute1和attrbite2值相等,我想要的是将节点内容合并到一个新节点。所以输出应该像
<xml>
<transformed relationship="merged">
<source attribute1="RSC1985s5c1" attribute2="6(17)"/>
<target attribute1="LRC1985s5c1" attribute2="6(17)1"/>
<target attribute1="LRC1985s5c4" attribute2="6(17)1"/>
<target attribute1="LRC1985s5c6" attribute2="6(17)2"/>
</transformed>
<transformed relationship="non-merged">
<source attribute1="RSC1985s5c2" attribute2="7(17)"/>
<target attribute1="LRC1985s5c2" attribute2="7(17)"/>
</transformed>
</xml>
因此前两个节点的source attribute1和attribute2值彼此相等,这就是我将它们组合为一个新节点的原因。源中的第三个节点与其他人不匹配,为什么我单独输出。我尝试使用foreach循环但无法正确解决问题。如果我们可以通过使用模板匹配来实现您的帮助。
具有相同子节点“source”属性的任何内容节点都应该组合在一起,而不管它们的位置如何。合并后的关系将变为“合并”,非合并项将变为“非合并”
答案 0 :(得分:1)
这可以通过Muenchian Grouping来实现
因为您需要匹配源元素上的两个单独属性,您可能需要使用连接键,如此
<xsl:key name="dupes"
match="content/source"
use="concat(@attribute1, '|', @attribute2)" />
选择一个连接字符来分隔两个属性值(在这种情况下是一个管道)是很重要的,这两个属性永远不会出现在两个属性值中。
通常,要匹配每个组中的第一个元素,您可以执行此操作
<xsl:apply-templates select="content/source
[generate-id() =
generate-id(key('dupes', concat(@attribute1, '|', @attribute2))[1])]" />
但是,您需要做一些额外的工作,因为您需要知道哪些源元素在组中有多个项目,哪些只包含单个项目。因此,要获得包含多个项目的组,您可以执行以下操作:
<xsl:apply-templates select="content/source
[generate-id() =
generate-id(key('dupes', concat(@attribute1, '|', @attribute2))[1])]
[count(key('dupes', concat(@attribute1, '|', @attribute2))) > 1]" />
这是完整的XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="dupes" match="content/source" use="concat(@attribute1, '|', @attribute2)"/>
<xsl:template match="/xml">
<xsl:copy>
<transformed relationship="merged">
<xsl:apply-templates select="content/source[generate-id() = generate-id(key('dupes', concat(@attribute1, '|', @attribute2))[1])][count(key('dupes', concat(@attribute1, '|', @attribute2))) > 1]"/>
</transformed>
<transformed relationship="non-merged">
<xsl:apply-templates select="content/source[generate-id() = generate-id(key('dupes', concat(@attribute1, '|', @attribute2))[1])][count(key('dupes', concat(@attribute1, '|', @attribute2))) = 1]"/>
</transformed>
</xsl:copy>
</xsl:template>
<xsl:template match="source">
<xsl:copy-of select="."/>
<xsl:copy-of select="key('dupes', concat(@attribute1, '|', @attribute2))/following-sibling::target[1]"/>
</xsl:template>
</xsl:stylesheet>
当应用于您的示例XML时,输出以下内容
<xml>
<transformed relationship="merged">
<source attribute1="RSC1985s5c1" attribute2="6(17)"/>
<target attribute1="LRC1985s5c1" attribute2="6(17)1"/>
<target attribute1="LRC1985s5c4" attribute2="6(17)1"/>
<target attribute1="LRC1985s5c6" attribute2="6(17)2"/>
</transformed>
<transformed relationship="non-merged">
<source attribute1="RSC1985s5c2" attribute2="7(17)"/>
<target attribute1="LRC1985s5c2" attribute2="7(17)"/>
</transformed>
</xml>