Xslt 按值对元素排序并删除重复项
我有以下意见:Xslt 按值对元素排序并删除重复项,xslt,sorting,select,Xslt,Sorting,Select,我有以下意见: <?xml version="1.0" encoding="utf-8"?> <NewTerms> <newTerm>XPath</newTerm> <newTerm>AutoValue</newTerm> <newTerm>XPath</newTerm> <newTerm>context</newTerm> <newTerm>A
<?xml version="1.0" encoding="utf-8"?>
<NewTerms>
<newTerm>XPath</newTerm>
<newTerm>AutoValue</newTerm>
<newTerm>XPath</newTerm>
<newTerm>context</newTerm>
<newTerm>AutoValue</newTerm>
<newTerm>language files</newTerm>
<newTerm>AutoValue</newTerm>
<newTerm>.NET</newTerm>
<newTerm>XPath</newTerm>
</NewTerms>
XPath
自动值
XPath
上下文
自动值
语言文件
自动值
.NET
XPath
我想对它进行排序,它与以下功能完美结合:
<xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()">
<xsl:sort select="."/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
问题是(显然)我得到了一个排序输出列表,其中的元素重复使用相同的值(例如XPath、AutoValue)。我想要一个没有重复值的排序列表。也就是说,我希望每个值在已排序的XML输出中只保留一次
请提供任何建议?您应该筛选您的排序选择:
<xsl:template match="@*|node()[not(preceding::node()=.)]">
<xsl:copy>
<xsl:apply-templates select="@*|node()">
<xsl:sort select="."/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
它将为您提供所需的输出:
<?xml version="1.0"?>
<NewTerms>
<newTerm>.NET</newTerm>
<newTerm>AutoValue</newTerm>AutoValueAutoValue
<newTerm>EPF</newTerm>
<newTerm>XPath</newTerm>XPathXPath
<newTerm>context</newTerm>
<newTerm>language files</newTerm>
</NewTerms>
.NET
自动值自动值自动值
EPF
XPathXPathXPath
上下文
语言文件
此样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kNewTermByValue" match="newTerm" use="."/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="NewTerms">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates
select="newTerm[count(.|key('kNewTermByValue',.)[1])=1]">
<xsl:sort/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
输出:
<NewTerms xp_0:noNamespaceSchemaLocation="../XSD\CC-CustomDocuTags.xsd" xmlns:xp_0="http://www.w3.org/2001/XMLSchema-instance">
<newTerm>.NET</newTerm>
<newTerm>AutoValue</newTerm>
<newTerm>context</newTerm>
<newTerm>EPF</newTerm>
<newTerm>language files</newTerm>
<newTerm>XPath</newTerm>
</NewTerms>
.NET
自动值
上下文
EPF
语言文件
XPath
注意:不要将属性和子项一起排序,因为在输出子项后无法输出属性。谢谢!我试着用key()函数来实现它。。。而且没有到达任何地方。我认为主要是bcos,我没有真正了解key()函数的工作原理和反应。请注意,这会删除属性。此外,我也不介意为小输入检查相同类型的兄弟姐妹;性能差异不会明显。但值得注意的是,使用键是更惯用的XSLT方法,并且可以在大型输入上获得显著的性能优势。我想我的政策是,至少在放弃钥匙时提到这一点。+1-更好的答案。我认为测试集合中第一个节点的
count(.| key('keyName',)[1])=1
方法比比较ID(即使我并不总是使用它)要漂亮得多。@lwburk:我也喜欢这个,因为集合论。但只有当你绝对确定两个操作数都是单例(没有一个是空的)时,它才起作用。现在我的回答被接受了,真是太遗憾了。有没有办法重新考虑它(对于所有其他正在寻找这样一个解决方案的人来说,都指向这个问题)?@rekaszeru:没问题。除了指数复杂的区分方法外,解决方案的唯一真正问题是将属性和节点子项排序在一起。我认为你应该修正这一点。