【问题标题】:XSLT select distinct values using attributesXSLT 使用属性选择不同的值
【发布时间】:2013-10-10 10:07:28
【问题描述】:

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

输入:

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

期望的输出:

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

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

谢谢

【问题讨论】:

    标签: xslt select unique distinct


    【解决方案1】:

    使用 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>
    

    【讨论】:

    • 对我来说这个错误'distinct-values()' is an unknown XSLT function.
    • 您需要使用 XSLT 2 处理器来运行该代码。
    • 请告诉我该怎么做。我正在使用 c#
    • 我从您的answer 获得了一个链接。谢谢!
    • @MartynasJusevičius,我认为您应该将其作为一个单独的问题提出,目前尚不清楚是否要根据节点 ID 或属性值对属性进行重复数据删除。但是&lt;for-each-group select="$attribute-sequence" group-by="."&gt;&lt;xsl:sequence select="."/&gt;&lt;/xsl:for-each-group&gt; 按属性值进行重复数据删除应该可以。对于使用$attribute-sequence/. 的节点ID 应该可以。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2017-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-17
      • 2020-12-03
      • 2015-01-25
      相关资源
      最近更新 更多