从包含冗余文本的XML元素列表中选择一个文本实例

从包含冗余文本的XML元素列表中选择一个文本实例,xml,xslt,xpath,Xml,Xslt,Xpath,我需要创建一个过滤器列表以应用于新闻列表。我有以下一段XML: <filters> <filter>cars</filter> <filter>cars</filter> <filter>animals</filter> <filter>house</filter> <filter>sports</filter> <filt

我需要创建一个过滤器列表以应用于新闻列表。我有以下一段XML:

<filters>
   <filter>cars</filter>
   <filter>cars</filter>
   <filter>animals</filter>
   <filter>house</filter>
   <filter>sports</filter>
   <filter>cars</filter>
   <filter>house</filter>
</filters>

汽车
汽车
动物
房子
体育
汽车
房子
我需要做的是将所有不同的过滤器打印给最终用户。所以我想运行XML,但只打印一个过滤器一次,这样称为“cars”的过滤器不会打印三次,而只打印一次。 事实上,我希望最终得到的XML如下所示:

<filters>
   <filter>cars</filter>
   <filter>animals</filter>
   <filter>house</filter>
   <filter>sports</filter>
</filters>

汽车
动物
房子
体育
这将导致XML中的一个过滤器实例

我该怎么做

提前谢谢

/Kim

使用:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:key name="k" match="filter" use="."/>

    <xsl:template match="filter[generate-id() != generate-id(key('k', .))]"/>

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

I.XSLT 1.0解决方案。

这一转变:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kFilterByVal" match="filter" use="."/>

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

 <xsl:template match=
 "filter[not(generate-id()
            =
             generate-id(key('kFilterByVal', .))
             )
         ]"/>
</xsl:stylesheet>

应用于提供的XML文档时

<filters>
    <filter>cars</filter>
    <filter>cars</filter>
    <filter>animals</filter>
    <filter>house</filter>
    <filter>sports</filter>
    <filter>cars</filter>
    <filter>house</filter>
</filters>
<filters>
   <filter>cars</filter>
   <filter>animals</filter>
   <filter>house</filter>
   <filter>sports</filter>
</filters>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*">
     <filters>
       <xsl:for-each-group select="*" group-by=".">
         <xsl:sequence select="."/>
       </xsl:for-each-group>
     </filters>   
 </xsl:template>
</xsl:stylesheet>

汽车
汽车
动物
房子
体育
汽车
房子
生成所需的正确结果

<filters>
    <filter>cars</filter>
    <filter>cars</filter>
    <filter>animals</filter>
    <filter>house</filter>
    <filter>sports</filter>
    <filter>cars</filter>
    <filter>house</filter>
</filters>
<filters>
   <filter>cars</filter>
   <filter>animals</filter>
   <filter>house</filter>
   <filter>sports</filter>
</filters>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*">
     <filters>
       <xsl:for-each-group select="*" group-by=".">
         <xsl:sequence select="."/>
       </xsl:for-each-group>
     </filters>   
 </xsl:template>
</xsl:stylesheet>

汽车
动物
房子
体育
解释


II。XSLT 2.0解决方案

<filters>
    <filter>cars</filter>
    <filter>cars</filter>
    <filter>animals</filter>
    <filter>house</filter>
    <filter>sports</filter>
    <filter>cars</filter>
    <filter>house</filter>
</filters>
<filters>
   <filter>cars</filter>
   <filter>animals</filter>
   <filter>house</filter>
   <filter>sports</filter>
</filters>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*">
     <filters>
       <xsl:for-each-group select="*" group-by=".">
         <xsl:sequence select="."/>
       </xsl:for-each-group>
     </filters>   
 </xsl:template>
</xsl:stylesheet>

当此转换应用于相同的XML文档(如上)时,会产生相同的正确结果。


解释:使用XSLT2.0指令。

您可能正在寻找
distinct-values()
函数。我认为您可以组合这两个模板(即
match=“filter[generate-id()=generate id(key('k'))]
match=“filter”
)一个人做
。这样,身份转换模板就完成了其余的工作。如果问题的海报对XSLT来说是新的,那么可以帮助理解它。@MartinHonnen,我使用了
!=
操作符而不是
not
函数。