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

时间:2012-03-19 13:13:30

标签: xml xslt xpath

我需要创建一个要应用于新闻列表的过滤器列表。我有以下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中的一个过滤器实例。

我该怎么做?

提前致谢!

/金

2 个答案:

答案 0 :(得分:1)

使用:

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

答案 1 :(得分:1)

<强>予。 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>

解释 Muenchian grouping method


<强> II。 XSLT 2.0解决方案:

<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文档(上面)上应用此转换时,会产生相同的正确结果。

解释:使用 <xsl:for-each-group> XSLT 2.0说明。