Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xslt 按值对元素排序并删除重复项_Xslt_Sorting_Select - Fatal编程技术网

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:没问题。除了指数复杂的区分方法外,解决方案的唯一真正问题是将属性和节点子项排序在一起。我认为你应该修正这一点。