我正在尝试使用 XSLT 将列表转换为不同的值列表。
输入:
<object name="obj1"/>
<object name="obj2"/>
<object name="obj1"/>
期望的输出:
<object>obj1</object>
<object>obj2</object>
有人知道如何在 XSLT 1.0 或 2.0 中完成它吗?
谢谢
使用 XSLT 2.0 和
<xsl:for-each select="distinct-values(//object/@name)">
<object><xsl:value-of select="."/></object>
</xsl:for-each>
或者
<xsl:for-each-group select="//object" group-by="@name">
<object><xsl:value-of select="current-grouping-key()"/></object>
</xsl:for-each-group>
对于 XSLT 1.0
对象.xml:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="objects.xsl"?>
<objects>
<object id="id1" name="obj1"/>
<object id="id2" name="obj2"/>
<object id="id3" name="obj1"/>
</objects>
对象.xsl:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="index1" match="*" use="@name" />
<xsl:template match="/">
<objects>
<xsl:for-each select="//*[generate-id() = generate-id(key('index1',@name)[1])]">
<object><xsl:value-of select="@name"/></object>
</xsl:for-each>
</objects>
</xsl:template>
</xsl:stylesheet>
这里发生了什么:
<xsl:key name="index1" match="*" use="@name" />
的函数定义索引。它必须在声明之外。key()
index1
xsl:template
match="*"
您一起定义它适用于所有元素。use="@name"
您一起定义搜索条件index1
。key("index1","obj1")
的节点组成的数组。@name
"obj1"
<object name="obj1" id="id1"/>
<object name="obj1" id="id3"/>
generate-id()
为给定节点生成唯一 ID 的函数。<object name="obj1" id="id1"/>
) 将返回类似"id0xfffffffff6ddca80obj1"
.generate-id()
将返回当前节点的 ID。xsl:for-each
循环//*
,条件是generate-id()
当前节点必须等于结果generate-id()
中的第一个节点key('index1',@name)
。这意味着它必须是第一个节点本身。@name
值xsl:value-of
。因为它只发生在key('index1',@name)
结果的第一个元素上,所以它只会被打印一次。