我想使用XSLT将一组文档转换为一个结构。我有正确的转换工作来连接文档。但是,我不知道文件中是否有重复的条目,我需要将其删除。
我需要知道如何通过id属性删除这些重复项(如果存在)。所有重复项都具有相同的ID。我知道它与key和generate-id函数有关。
<root>
<item id="1001">A</item>
<item id="1003">C</item>
<item id="1004">D</item>
<item id="1002">B</item>
<item id="1001">A</item>
<item id="1003">C</item>
<item id="1004">D</item>
<item id="1005">E</item>
</root>
我需要针对上述内容进行XSLT 1.0转换,基于以下内容......
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
另外,有人能够向我解释它是如何运作的吗?一点菜鸟......
提前致谢...
答案 0 :(得分:3)
通常使用generate-id()
来提供解决方案,但我个人更喜欢不使用generate-id的稍微不同的变体: -
<xsl:key name="items" match="item" use="@id" />
<xsl:template match="root">
<root>
<xsl:copy-of select="item[count(key('items',@id)[1]|.)=1]" />
</root>
</xsl:template>
首先,使用id属性作为查找键创建一个包含所有item元素的键。 key
生成一个有效的索引,可用于查找项目。
该技术依赖于以下事实:使用|
运算符创建节点集时,您将获得一组唯一的节点。换句话说,如果在|
运算符的两侧找到相同的节点,它只会出现在结果集中一次。
表达式: -
key('items',@id)
将返回具有特定ID的项目节点集。所以: -
key('items',@id)[1]
将只返回找到的具有该特定ID且可重复的节点之一(重复使用此表达式始终返回相同的节点)。
因此表达式: -
count(key('items',@id)[1]|.)=1
对于具有特定id值的item
节点只能为true。
copy-of
因此仅对具有不同ID的一个项目节点进行深层复制。
答案 1 :(得分:3)
这是@AnthonyWJones提到的generate-id()
方式。我觉得这个人在人脑中更容易。结果没有区别,选择你最喜欢的。
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:key name="kItemById" match="item" use="@id" />
<xsl:template match="root">
<copy>
<xsl:copy-of select="
item[generate-id() = generate-id(key('kItemById', @id)[1])]
" />
</copy>
</xsl:template>
</xsl:stylesheet>
简而言之:
item[generate-id() = generate-id(key('kItemById', @id)[1])]
表示:“所有<item>
s,其唯一ID等于第一个项目的唯一ID,具有相同的@id
值。”