计算xslt 1.0中逗号分隔值中的唯一值

计算xslt 1.0中逗号分隔值中的唯一值,xslt,xpath,xslt-1.0,Xslt,Xpath,Xslt 1.0,我在XML文件中有一个节点: <TEST_STRING>12,13,12,14</TEST_STRING> 12,13,12,14 我需要计算这个字符串有多少个唯一的数字/值。例如,在这种情况下,有两个唯一的值,即13和14 老实说,我还不能建造任何东西。在XSLT1.0中似乎很困难,但我的系统只支持1.0 有什么解决方案吗?如果您的处理器支持节点集扩展函数(或Microsoft),那么您可以分两步完成,首先拆分字符串并构建每个值一个元素的XML片段,然后使用普通的X

我在XML文件中有一个节点:

<TEST_STRING>12,13,12,14</TEST_STRING>
12,13,12,14
我需要计算这个字符串有多少个唯一的数字/值。例如,在这种情况下,有两个唯一的值,即13和14

老实说,我还不能建造任何东西。在XSLT1.0中似乎很困难,但我的系统只支持1.0


有什么解决方案吗?

如果您的处理器支持
节点集
扩展函数(或Microsoft),那么您可以分两步完成,首先拆分字符串并构建每个值一个元素的XML片段,然后使用普通的XPath技术查找单例

第一步可以使用尾部递归模板完成:

<xsl:template name="splitString">
  <xsl:param name="str"/>
  <xsl:choose>
    <xsl:when test="contains($str, ',')">
      <item><xsl:value-of select="substring-before($str, ',')"/></item>
      <xsl:call-template name="splitString">
        <xsl:with-param name="str" select="substring-after($str, ',')"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <item><xsl:value-of select="$str"/></item>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>
下一个挑战是找到单例,您可以使用以下表达式

$items/item[not(. = (preceding-sibling::item | following-sibling::item))]
(有更有效的方法使用密钥,但对于少量项目,可能不值得费心)。所以要数单身汉

<xsl:value-of select="count($items/item[not(. = (preceding-sibling::item | following-sibling::item))])"/>

如果您的处理器支持
节点集
扩展函数(或Microsoft),那么您可以分两步完成,首先拆分字符串并构建每个值一个元素的XML片段,然后使用普通XPath技术查找单例

第一步可以使用尾部递归模板完成:

<xsl:template name="splitString">
  <xsl:param name="str"/>
  <xsl:choose>
    <xsl:when test="contains($str, ',')">
      <item><xsl:value-of select="substring-before($str, ',')"/></item>
      <xsl:call-template name="splitString">
        <xsl:with-param name="str" select="substring-after($str, ',')"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <item><xsl:value-of select="$str"/></item>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>
下一个挑战是找到单例,您可以使用以下表达式

$items/item[not(. = (preceding-sibling::item | following-sibling::item))]
(有更有效的方法使用密钥,但对于少量项目,可能不值得费心)。所以要数单身汉

<xsl:value-of select="count($items/item[not(. = (preceding-sibling::item | following-sibling::item))])"/>

没有节点集也可以。当然,它不是最优的(您好,画家Shlemiel),但它非常简单——只有在前面或后面没有给定字符串的情况下,才可以使用递增计数器

模板

<xsl:template name="calcUnique">
    <xsl:param name="str"/>
    <xsl:param name="back"/>
    <xsl:param name="count"/>

    <xsl:if test="$str">
        <xsl:choose>
            <xsl:when test="contains($str, ',')">
                <xsl:variable name="part" select="substring-before($str, ',')"/>
                <xsl:call-template name="calcUnique">
                    <xsl:with-param name="str" select="substring-after($str, ',')"/>
                    <xsl:with-param name="back" select="concat($back, ',', $part)"/>
                    <xsl:with-param name="count">
                        <xsl:choose>
                            <xsl:when test="contains(concat($str, ','), concat(',', $part, ',')) or contains(concat($back, ','), concat(',', $part, ','))">
                                <xsl:value-of select="$count"/>
                            </xsl:when>
                            <xsl:otherwise><xsl:value-of select="$count + 1"/></xsl:otherwise>
                        </xsl:choose>
                    </xsl:with-param>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:choose>
                    <xsl:when test="contains(concat($back, ','), concat(',', $str, ','))">
                        <xsl:value-of select="$count"/>
                    </xsl:when>
                    <xsl:otherwise><xsl:value-of select="$count + 1"/></xsl:otherwise>
                </xsl:choose>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
</xsl:template>
    <xsl:variable name="result">
        <xsl:call-template name="calc">
            <xsl:with-param name="str" select="TEST_STRING"/>
            <xsl:with-param name="back" select="''"/>
            <xsl:with-param name="count" select="0"/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:value-of select="$result"/>

示例用法

<xsl:template name="calcUnique">
    <xsl:param name="str"/>
    <xsl:param name="back"/>
    <xsl:param name="count"/>

    <xsl:if test="$str">
        <xsl:choose>
            <xsl:when test="contains($str, ',')">
                <xsl:variable name="part" select="substring-before($str, ',')"/>
                <xsl:call-template name="calcUnique">
                    <xsl:with-param name="str" select="substring-after($str, ',')"/>
                    <xsl:with-param name="back" select="concat($back, ',', $part)"/>
                    <xsl:with-param name="count">
                        <xsl:choose>
                            <xsl:when test="contains(concat($str, ','), concat(',', $part, ',')) or contains(concat($back, ','), concat(',', $part, ','))">
                                <xsl:value-of select="$count"/>
                            </xsl:when>
                            <xsl:otherwise><xsl:value-of select="$count + 1"/></xsl:otherwise>
                        </xsl:choose>
                    </xsl:with-param>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:choose>
                    <xsl:when test="contains(concat($back, ','), concat(',', $str, ','))">
                        <xsl:value-of select="$count"/>
                    </xsl:when>
                    <xsl:otherwise><xsl:value-of select="$count + 1"/></xsl:otherwise>
                </xsl:choose>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
</xsl:template>
    <xsl:variable name="result">
        <xsl:call-template name="calc">
            <xsl:with-param name="str" select="TEST_STRING"/>
            <xsl:with-param name="back" select="''"/>
            <xsl:with-param name="count" select="0"/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:value-of select="$result"/>

没有节点集也可以。当然,它不是最优的(您好,画家Shlemiel),但它非常简单——只有在前面或后面没有给定字符串的情况下,才可以使用递增计数器

模板

<xsl:template name="calcUnique">
    <xsl:param name="str"/>
    <xsl:param name="back"/>
    <xsl:param name="count"/>

    <xsl:if test="$str">
        <xsl:choose>
            <xsl:when test="contains($str, ',')">
                <xsl:variable name="part" select="substring-before($str, ',')"/>
                <xsl:call-template name="calcUnique">
                    <xsl:with-param name="str" select="substring-after($str, ',')"/>
                    <xsl:with-param name="back" select="concat($back, ',', $part)"/>
                    <xsl:with-param name="count">
                        <xsl:choose>
                            <xsl:when test="contains(concat($str, ','), concat(',', $part, ',')) or contains(concat($back, ','), concat(',', $part, ','))">
                                <xsl:value-of select="$count"/>
                            </xsl:when>
                            <xsl:otherwise><xsl:value-of select="$count + 1"/></xsl:otherwise>
                        </xsl:choose>
                    </xsl:with-param>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:choose>
                    <xsl:when test="contains(concat($back, ','), concat(',', $str, ','))">
                        <xsl:value-of select="$count"/>
                    </xsl:when>
                    <xsl:otherwise><xsl:value-of select="$count + 1"/></xsl:otherwise>
                </xsl:choose>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
</xsl:template>
    <xsl:variable name="result">
        <xsl:call-template name="calc">
            <xsl:with-param name="str" select="TEST_STRING"/>
            <xsl:with-param name="back" select="''"/>
            <xsl:with-param name="count" select="0"/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:value-of select="$result"/>

示例用法

<xsl:template name="calcUnique">
    <xsl:param name="str"/>
    <xsl:param name="back"/>
    <xsl:param name="count"/>

    <xsl:if test="$str">
        <xsl:choose>
            <xsl:when test="contains($str, ',')">
                <xsl:variable name="part" select="substring-before($str, ',')"/>
                <xsl:call-template name="calcUnique">
                    <xsl:with-param name="str" select="substring-after($str, ',')"/>
                    <xsl:with-param name="back" select="concat($back, ',', $part)"/>
                    <xsl:with-param name="count">
                        <xsl:choose>
                            <xsl:when test="contains(concat($str, ','), concat(',', $part, ',')) or contains(concat($back, ','), concat(',', $part, ','))">
                                <xsl:value-of select="$count"/>
                            </xsl:when>
                            <xsl:otherwise><xsl:value-of select="$count + 1"/></xsl:otherwise>
                        </xsl:choose>
                    </xsl:with-param>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:choose>
                    <xsl:when test="contains(concat($back, ','), concat(',', $str, ','))">
                        <xsl:value-of select="$count"/>
                    </xsl:when>
                    <xsl:otherwise><xsl:value-of select="$count + 1"/></xsl:otherwise>
                </xsl:choose>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:if>
</xsl:template>
    <xsl:variable name="result">
        <xsl:call-template name="calc">
            <xsl:with-param name="str" select="TEST_STRING"/>
            <xsl:with-param name="back" select="''"/>
            <xsl:with-param name="count" select="0"/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:value-of select="$result"/>


您具体使用哪种XSLT 1.0处理器?您具体使用哪种XSLT 1.0处理器?太好了,我将尝试两种解决方案,有节点集和无节点集。我会回到你身边的。是的,是我的错。修复。太好了,我将尝试两种解决方案,有节点集和无节点集。我会回到你身边的。是的,是我的错。固定的。