我正在尝试使用 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()index1xsl:templatematch="*"您一起定义它适用于所有元素。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)结果的第一个元素上,所以它只会被打印一次。