XSLT、XPath唯一子节点—完全不选择非唯一节点的唯一问题

XSLT、XPath唯一子节点—完全不选择非唯一节点的唯一问题,xslt,xpath,Xslt,Xpath,我试过: John Ben Mark Luke 您的问题是您正在使用=运算符 这是错误的--始终避免使用=运算符并始终使用not()函数和=运算符 以下是正确的解决方案: Ben Mark Luke <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/>

我试过:

John Ben Mark Luke

您的问题是您正在使用
=运算符

这是错误的--始终避免使用
=运算符并始终使用
not()
函数和
=
运算符

以下是正确的解决方案

Ben Mark Luke
<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:template match="/*">
    <xsl:for-each select="parent">
      <xsl:for-each select="child[not(name = preceding::name)]">
        <xsl:value-of select="concat(name, ' ')"/>
      </xsl:for-each>
    </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>
<root>
  <parent>
    <child>
     <name>John</name>
    </child>
    <child>
      <name>Ben</name>
    </child>
  </parent>
  <parent>
    <child>
     <name>John</name>
    </child>
    <child>
     <name>Mark</name>
    </child>
    <child>
      <name>Luke</name>
    </child>
 </parent>
</root>
解释:以下是W3C XPath 1.0规范如何定义
的语义=操作员:

“如果要比较的一个对象是 节点集,另一个是字符串, 那么,如果 并且仅当 节点集,以便 在上执行比较 节点和其他节点的字符串值 字符串是真的。”

这意味着

John Ben Mark Luke 
如果
节点集中只有一个节点不等于
's'
,则始终为真

这不是我们想要的语义

另一方面,

's' != node-set
仅当
节点集中没有等于
's'
的节点时,才为true

这正是我们想要的比较


请注意:您选择的分组技术为O(N^2),只应在非常小的重复数据集上使用。如果需要效率,请务必使用Muenchian方法进行分组(讨论或演示此问题不在本问题范围内)。

好问题,+1。请参阅我的答案以了解解释和正确的解决方案。:)这适用于小型文档,但请注意,它依赖于将每个节点与它前面的所有节点进行比较。如果您的文档是一个实际的、冗长的文档,那么执行此文档的时间将大幅增加。@LaustN:当然,我不支持这种O(N^2)技术,只是回答了具体的问题。当需要效率时,使用Muenchian方法。我刚刚编辑了我的答案,最后一个注释是这样写的。@Mrk Mnl:对于小文档,这是可以的。如果您希望了解并使用两种不同的分组方法(一种用于小文档,另一种用于大文档),这是可以的。不管文档大小如何,大多数人只喜欢使用一种分组方法,即Muenchian分组方法。谢谢,如果我再次遇到这个问题,在这种情况下,我最多只能有10个节点,作为XSLT方面的专家,我宁愿现在还不去学习它。我想知道在这种情况下是否不应该优化XSLT编译器/解释器以进行分组。。
John Ben Mark Luke 
's' != node-set
not('s' = node-set())