所以,我以前的帖子是这样的: Matching the first element when it can occure in different places of the hierarchy?
Muenchian小组似乎可以工作,但是现在我遇到的问题是我有多个。例如这样的
<x>
<a>
<b>
<d value="1"></d>
<b/>
<b>
<c>
<d value="2"></d>
<d value="1"></d>
</c>
<d value="1">
<d value="2">
<b/>
</a>
<a>
<b>
<d value="3"></d>
<b/>
<b>
<c>
<d value="1"></d>
<d value="2"></d>
</c>
<d value="1">
<d value="3">
<b/>
</a>
</x>
您可以看到,我在a [1]和a [2]中有d / @ value =“ 1”。我想摆脱这个d中尚未出现的每个d的问题。因此,在这里我想将第一个具有value =“ 1”和value =“ 2”的a [1]和a [2]以及第一个具有value =“ 3”的属性保留在a [2]中,并摆脱所有其他。
产生这样的输出:
<x>
<a>
<b>
<d value="1"></d>
<b/>
<b>
<c>
<d value="2"></d>
</c>
<b/>
</a>
<a>
<b>
<d value="3"></d>
<b/>
<b>
<c>
<d value="1"></d>
<d value="2"></d>
</c>
<b/>
</a>
</x>
我这样尝试过:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="d-by-value" match="d" use="@value" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- remove duplicate d's -->
<xsl:template match="a//d[count(. | key('d-by-value', @value)[1]) != 1]"/>
</xsl:stylesheet>
这只会导致整个xml中的第一个d / @ value =“ 1”保留(因为当然,整个文件中的总计数> 1在不同的a内,所以我也尝试了这个:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="d-by-value" match="d" use="@value" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- remove duplicate d's -->
<xsl:template match="a//d[count(. | key('d-by-value', @value)[1]) != 1]"/>
<xsl:template match="d" name="remove-d"/>
<xsl:template match="paragr">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="node()"/>
<xsl:for-each select=".//d[count(. | key('d-by-value', @value)[1]) != 1]) = 1]">
<xsl:call-template name="remove-d"/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
但是,这似乎摆脱了所有的d。有什么想法吗?
编辑:更正了xsl:for-each选择。进行了复制/粘贴错误,并更正了该有价值的东西,如下面的评论所示。
答案 0 :(得分:0)
如果要删除给定a
元素的重复值,则需要在键匹配中引用a
<xsl:key name="d-by-value" match="d" use="concat(generate-id(ancestor::a), '|', @value)" />
在这里,generate-id
将为XML中的节点创建唯一的代码。
使用密钥时,模板匹配中将需要类似的逻辑
<xsl:template match="a//d[count(. | key('d-by-value', concat(generate-id(ancestor::a), '|', @value))[1]) != 1]"/>
尝试使用此XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="d-by-value" match="d" use="concat(generate-id(ancestor::a), '|', @value)" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- remove duplicate d's -->
<xsl:template match="a//d[count(. | key('d-by-value', concat(generate-id(ancestor::a), '|', @value))[1]) != 1]"/>
</xsl:stylesheet>