我正在尝试使用XSLT将列表转换为不同的值列表。
输入:
<object name="obj1"/>
<object name="obj2"/>
<object name="obj1"/>
期望的输出:
<object>obj1</object>
<object>obj2</object>
有人知道如何在XSLT 1.0或2.0中完成它吗?
THX
答案 0 :(得分:15)
使用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>
答案 1 :(得分:0)
对于XSLT 1.0
objects.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>
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()
的{{1}}函数定义一个索引。它必须在index1
声明之外。xsl:template
定义它适用于所有元素。match="*"
为use="@name"
定义搜索条件。index1
将返回一个由节点组成的数组,这些节点的属性key("index1","obj1")
等于@name
:["obj1"
,<object name="obj1" id="id1"/>
]。<object name="obj1" id="id3"/>
函数来为给定节点生成唯一ID。generate-id()
)会返回类似<object name="obj1" id="id1"/>
的内容。"id0xfffffffff6ddca80obj1"
将返回当前节点的ID。generate-id()
,您要开始xsl:for-each
循环,条件是当前节点//*
必须等于generate-id()
结果中第一个节点的generate-id()
。这意味着它必须是第一个节点本身。key('index1',@name)
打印当前的@name
值。由于它仅发生在xsl:value-of
结果的第一个元素中,因此只会打印一次。