XSLT使用属性选择不同的值

时间:2013-10-10 10:07:29

标签: xslt select unique distinct

我正在尝试使用XSLT将列表转换为不同的值列表。

输入:

<object name="obj1"/>
<object name="obj2"/>
<object name="obj1"/>

期望的输出:

<object>obj1</object>
<object>obj2</object>

有人知道如何在XSLT 1.0或2.0中完成它吗?

THX

2 个答案:

答案 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>

这是怎么回事:

  1. 使用<xsl:key name="index1" match="*" use="@name" />为名为key()的{​​{1}}函数定义一个索引。它必须在index1声明之外。
  2. 使用xsl:template定义它适用于所有元素。
  3. 使用match="*"use="@name"定义搜索条件。
  4. 现在index1将返回一个由节点组成的数组,这些节点的属性key("index1","obj1")等于@name:["obj1"<object name="obj1" id="id1"/>]。
  5. 您将需要<object name="obj1" id="id3"/>函数来为给定节点生成唯一ID。
  6. 使用参数调用generate-id(generate-id())会返回类似<object name="obj1" id="id1"/>的内容。
  7. 不带参数调用的"id0xfffffffff6ddca80obj1"将返回当前节点的ID。
  8. 对于所有元素generate-id(),您要开始xsl:for-each循环,条件是当前节点//*必须等于generate-id()结果中第一个节点的generate-id() 。这意味着它必须是第一个节点本身。
  9. 您使用key('index1',@name)打印当前的@name值。由于它仅发生在xsl:value-of结果的第一个元素中,因此只会打印一次。