Xslt 基于属性值的内容节点合并与重构
我有一个包含以下标记的xml文件Xslt 基于属性值的内容节点合并与重构,xslt,Xslt,我有一个包含以下标记的xml文件 <xml> <content relationship="regula"> **<source attribute1="RSC1985s5c1" attribute2="6(17)"/>** <target attribute1="LRC1985s5c1" attribute1="6(17)1"/> </content> <content rela
<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>
所以前两个节点的源attribute1和attribute2值彼此相等,这就是为什么我将它们合并为一个新节点。源代码中的第三个节点与其他节点不匹配,这就是我单独输出该节点的原因。我尝试使用foreach循环,但无法找到合适的解决方法。感谢您的帮助,如果我们可以通过使用模板匹配来实现
任何具有子节点“源”相同属性的内容节点都应分组在一起,而不管它们的位置如何。对于合并的项目和未合并的项目,关系将更改为“合并”。它将是“未合并”这可以通过Muenchian分组实现 因为您需要在源元素上匹配两个单独的属性,所以可能需要使用串联键,如下所示
<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>
这可以通过明钦族分组来实现 因为您需要在源元素上匹配两个单独的属性,所以可能需要使用串联键,如下所示
<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>
@\u atif:是否应该合并任何两个具有“公共”子节点的内容
节点?只有两个相邻的内容节点要合并吗?如果两个以上的内容节点具有“公共”元素,该怎么办?由于合并,关系
属性真的应该丢失吗?在这个问题上有太多的事情不清楚。请编辑并提供缺少的信息。任何具有子节点“源”相同属性的内容节点,无论其位置如何,都应分组在一起。对于合并的项目和未合并的项目,关系将更改为“合并”。它将是“未合并”@_atif:好吧,在评论中这样说很好,但它属于问题——请编辑您的问题并在那里提供此信息。另外,您没有回答我的问题,如果要合并两个以上的节点,那么预期的输出id应该是什么?请在您的问题中提供这样的示例。我绝对不愿意猜测你可能甚至没有想到的事情…@(如果):有"普通"子节点的任何两个content
节点是否应该合并??只有两个相邻的内容节点要合并吗?如果两个以上的内容节点具有“公共”元素,该怎么办?由于合并,关系
属性真的应该丢失吗?在这个问题上有太多的事情不清楚。请编辑并提供缺少的信息。任何具有子节点“源”相同属性的内容节点,无论其位置如何,都应分组在一起。对于合并的项目和未合并的项目,关系将更改为“合并”。它将是“未合并”@_atif:好吧,在评论中这样说很好,但它属于问题——请编辑您的问题并在那里提供此信息。另外,您没有回答我的问题,如果要合并两个以上的节点,那么预期的输出id应该是什么?请在您的问题中提供这样的示例。我绝对不愿意去猜测那些你可能根本没想过的事情。。。