Xml XSLT选择不重复的节点值

Xml XSLT选择不重复的节点值,xml,xslt,Xml,Xslt,我试图从列表中获取不重复的节点值。我试过很多建议,但都不管用。 这是我的源XML <Records> <Record> <Files> <File> <Name>A</Name> </File> <File> <Name>B</Name> </File> <

我试图从列表中获取不重复的节点值。我试过很多建议,但都不管用。 这是我的源XML

<Records>
  <Record>
    <Files>
      <File>
        <Name>A</Name>
      </File>
      <File>
        <Name>B</Name>
      </File>
      <File>
        <Name>B</Name>
      </File>
    </Files>
  </Record>
  <Record>
    <Files>
      <File>
        <Name>A</Name>
      </File>
      <File>
        <Name>B</Name>
      </File>
      <File>
        <Name>C</Name>
      </File>
      <File>
        <Name>C</Name>
      </File>
    </Files>
  </Record>
</Records>
第一个逗号分隔的集合来自第一个记录,第二个集合(在“|”)来自第二个记录。 (分隔符位置、空格等不是我的问题,而是删除重复项)

我现在的代码是这样的

A,B | A,B,C
<xsl:key name="NameId" match="Name" use="." />

<xsl:for-each select="Records/Record">
  <xsl:call-template name="doeach_record"/>
  <xsl:text>|</xsl:text>
</xsl:for-each>

<xsl:template name="doeach_record">
  <xsl:for-each select="Files/File">
    <xsl:if test="generate-id(Name) = generate-id(key('NameId', Name)[1])">
      <xsl:value-of select="Name"/>
    </xsl:if>
    <xsl:text>,</xsl:text>
  </xsl:for-each>
</xsl:template>
A,B | ,,C

自2007年以来,XSLT2.0已经有了各种实现,如Saxon 9、XmlPrime、Altova,您可以在这些实现中使用
。如果您确实限于XSLT 1.0,那么您需要定义一个键,该键使用祖先
记录的生成id以及
名称
,例如
,然后您可以使用通常的基于XSLT 1.0键的Muenchian分组/不同值方法。

正如Martin所指出的,在XSLT 2.0中,
不同值()
是你的朋友

对于XSLT2.0,这里有一种稍微不同的方法。这包括排序,以防输入XML尚未按字母顺序排列

<xsl:output method="text"/>

<xsl:template match="/">
    <xsl:for-each select="/Records/Record">
        <xsl:for-each select="distinct-values(Files/File/Name)">
            <xsl:sort/>
            <xsl:value-of select="."/>
            <xsl:if test="position() != last()">,</xsl:if>
        </xsl:for-each>
        <xsl:if test="position() != last()"> | </xsl:if>
    </xsl:for-each>
</xsl:template>

,
|