1

假设我有以下序列:

<node-1> <children-A attr="100" /> </node-1>
<node-1> <children-A attr="200" /> </node-1>     <!--not a duplicate -->
<node-1> <children-B /> </node-1>
<node-1> <children-B /> </node-1>                <!-- duplicate off the above -->
<node-1> <children-A /> <children-B /> </node-1> <!--not a duplicate -->

我想获得所有唯一的“node-1”,以便输出为:

<node-1> <children-A attr="100" /> </node-1>
<node-1> <children-A attr="200" /> </node-1>
<node-1> <children-B /> </node-1>
<node-1> <children-A /> <children-B /> </node-1>

注意:仅<node-1> <children-B /> </node-1>已删除。

使用 Saxon 9.1.0.8,我已经尝试过distinct-value($S),但返回类型是xs:anyAtomicType并且我不知道如何将其转换为正确的序列(如果可能的话!)。

但是,我可以count(distinct-value($S))用来检查返回的元素数量是否与唯一元素的实际数量匹配,实际上它确实匹配。

4

2 回答 2

1

使用http://www.xsltfunctions.com/xsl/functx_distinct-deep.html(反过来使用http://www.xsltfunctions.com/xsl/functx_is-node-in-sequence-deep-equal.html其中在转而使用 XSLT/XPath 2.0 功能deep-equal)您可以使用<xsl:variable name="distinct-seq" select="functx:distinct-deep($your-sequence)"/>

或者,如果您不想或不能包含 functx 库,则需要在

<xsl:variable name="distinct-seq"
  select="for $pos in (1 to count($your-sequence))
          return $your-sequence[$pos]
                               [not(some $node in $your-sequence[position() lt $pos] satisfies deep-equal(., $node))]"/>
于 2013-03-19T12:41:28.450 回答
0

这实际上是一个 XPath 2.0 问题。

使用

   for $vN in /*/*
     return
        $vN[not(/*/*[. >> $vN and deep-equal(., $vN)])]

基于 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:strip-space elements="*"/>

 <xsl:template match="/">
  <xsl:sequence select=
  "for $vN in /*/*
     return
        $vN[not(/*/*[. >> $vN and deep-equal(., $vN)])]

  "/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于以下 XML 文档时(提供的片段包装到单个顶部元素中):

<t>
 <node-1> <children-A attr="100" /> </node-1>
 <node-1> <children-A attr="200" /> </node-1> 
 <node-1> <children-B /> </node-1>
 <node-1> <children-B /> </node-1> 
 <node-1> <children-A /> <children-B /> </node-1> 
</t>

产生了想要的正确结果:

<node-1>
   <children-A attr="100"/>
</node-1>
<node-1>
   <children-A attr="200"/>
</node-1>
<node-1>
   <children-B/>
</node-1>
<node-1>
   <children-A/>
   <children-B/>
</node-1>
于 2013-03-20T04:18:58.767 回答