从包含冗余文本的XML元素列表中选择一个文本实例
我需要创建一个过滤器列表以应用于新闻列表。我有以下一段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
<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
函数。