我试图从列表中获取非重复节点值。我已经尝试过很多建议,但对我来说没什么用。 这是我的源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
第一个逗号分隔集来自第一个记录,第二个集合(“|”之后)来自第二个记录。 (分隔符放置,空格等...不是我的问题,它是删除重复项)
Code I我现在看起来像这样
<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
答案 0 :(得分:1)
自2007年以来,XSLT 2.0有各种各样的实现,如Saxon 9,XmlPrime,Altova,您可以使用<xsl:template match="Record"><xsl:value-of select="distinct-values(Files/File/Name)" separator=","/></xsl:template>
。如果您确实受限于XSLT 1.0,则需要定义一个密钥,该密钥将祖先Record
的生成ID与Name
一起使用,例如<xsl:key name="unique" match="File/Name" use="concat(generate-id(ancestor::Record), '|', .)"/>
,那么您可以使用基于XSLT 1.0密钥的Muenchian分组/不同值方法。
答案 1 :(得分:1)
正如Martin所说,在XSLT 2.0中,distinct-values()
是你的朋友。
这是XSLT 2.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>