需要仅选择xsl中的Unique值

时间:2014-12-11 13:37:22

标签: xslt xslt-1.0 ibm-datapower

输入具有多个相同键值的XML:

<ns2:enumCollection>
    <ns3:item>
        <ns3:key>000</ns3:key>
        <ns3:value>GRS Tracker00CA1</ns3:value>
    </ns3:item>
    <ns3:item>
        <ns3:key>000</ns3:key>
        <ns3:value>GRS Tracker00CA1</ns3:value>
    </ns3:item>
    <ns3:item>
        <ns3:key>001</ns3:key>
        <ns3:value>GRS Tracker00CA2</ns3:value>
    </ns3:item>                             
</ns2:enumCollection>

预期产出结果

<ns2:enumCollection>
    <ns3:item>
        <ns3:key>000</ns3:key>
        <ns3:value>GRS Tracker00CA1</ns3:value>
    </ns3:item>
    <ns3:item>
        <ns3:key>001</ns3:key>
        <ns3:value>GRS Tracker00CA2</ns3:value>
    </ns3:item>                             
</ns2:enumCollection>

需要有关此转型的帮助。 我正在尝试使用xsl:Key函数但无法成功转换。

1 个答案:

答案 0 :(得分:1)

首先要注意的是,您的输入XML具有名称空间前缀,但没有声明它们,这是不允许的。我假设您的实际XML确实拥有它们!出于这个答案的目的,我将构建一些名称空间

<ns2:enumCollection xmlns:ns2="ns2" xmlns:ns3="ns3">
    <ns3:item>
        <ns3:key>000</ns3:key>
        <ns3:value>GRS Tracker00CA1</ns3:value>
    </ns3:item>
    <ns3:item>
        <ns3:key>000</ns3:key>
        <ns3:value>GRS Tracker00CA1</ns3:value>
    </ns3:item>
    <ns3:item>
        <ns3:key>001</ns3:key>
        <ns3:value>GRS Tracker00CA2</ns3:value>
    </ns3:item>                             
</ns2:enumCollection>

要获得唯一值,您可以使用一种名为Muenchian分组的技术,因为它涉及最初获取唯一值,但在您的情况下,您将丢弃“组”的其余部分。

如果您按itemskey进行分组,那么您的XML实际上应该是这样的

<xsl:key name="element-key" match="ns3:item" use="ns3:key" /> 

然后,要获取“不同”值,您可以执行此操作以获取每个item的第一次出现的key

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns2="ns2" xmlns:ns3="ns3">
    <xsl:output method="xml" indent="yes"/>
    <xsl:key name="element-key" match="ns3:item" use="ns3:key" /> 

    <xsl:template match="ns2:enumCollection">
       <xsl:copy>
          <xsl:apply-templates select="ns3:item[generate-id() = generate-id(key('element-key', ns3:key)[1])]"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="@*|node()">
       <xsl:copy>
           <xsl:apply-templates select="@*|node()"/>
       </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

或者,您可以使用模板“丢弃”不是每组中第一个的元素

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns2="ns2" xmlns:ns3="ns3">
    <xsl:output method="xml" indent="yes"/>
    <xsl:key name="element-key" match="ns3:item" use="ns3:key" /> 

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="ns3:item[generate-id() != generate-id(key('element-key', ns3:key)[1])]" />
</xsl:stylesheet>

这两个输出以下

<ns2:enumCollection xmlns:ns2="ns2" xmlns:ns3="ns3">
    <ns3:item>
        <ns3:key>000</ns3:key>
        <ns3:value>GRS Tracker00CA1</ns3:value>
    </ns3:item>
    <ns3:item>
        <ns3:key>001</ns3:key>
        <ns3:value>GRS Tracker00CA2</ns3:value>
    </ns3:item>
</ns2:enumCollection>