XSLT 2.0如何在输出的tokenize()中测试position()

时间:2018-10-23 20:56:41

标签: xslt xpath xslt-2.0

在XSLT 2.0中,我有一个参数,它以分隔的文档名称字符串形式出现,例如: ms609_0080.xml~ms609_0176.xml~ms609_0210.xml~ms609_0418.xml

tokenize()将此字符串并用xsl:for-each在其间循环,以将每个文档传递给key。然后,我将来自键的结果组装成一个逗号分隔的字符串,以输出到屏幕。

<xsl:variable name="list_of_corresp_events">
   <xsl:variable name ="tokenparam" select="tokenize($paramCorrespdocs,'~')"/>
   <xsl:for-each select="$tokenparam">
      <xsl:choose>
          <xsl:when test=".[position() != last()]">
               <xsl:value-of select="document(concat($paramSaxondatapath, .))/(key('correspkey',$correspid))/@xml:id"/>
          </xsl:when>
          <xsl:otherwise>
               <xsl:value-of select="concat(document(concat($paramSaxondatapath, .))/(key('correspkey',$correspid))/@xml:id, ', ')"/>
          </xsl:otherwise>
      </xsl:choose>
   </xsl:for-each>
</xsl:variable>

一切正常,除了当我输出变量$list_of_corresp_events时,它看起来类似于以下内容,并带有意外的逗号:

ms609-0080-2, ms609-0176-1, ms609-0210-1, ms609-0418-1,

通常不应基于test=".[position() != last()]"出现最后一个逗号?排名可能不适用于标记化数据吗?我没有找到将string-join()应用于此的方法。

非常感谢。

3 个答案:

答案 0 :(得分:2)

改进@ zx485的解决方案,请尝试

<xsl:for-each select="$tokenparam">
   <xsl:if test="position()!=1">, </xsl:if>
   <xsl:value-of select="document(concat($paramSaxondatapath, .))/(key('correspkey',$correspid))/@xml:id"/>
</xsl:for-each>

这里有两件事:

(a)您不需要在两个条件分支中重复相同的代码

(b)在除第一个项目之前的每个项目之前输出逗号分隔符,比在除最后一个项目之外的每个项目之后输出逗号分隔符更为有效。这是因为评估last()涉及昂贵的前瞻。

答案 1 :(得分:1)

更改

<xsl:when test=".[position() != last()]">

<xsl:when test="position() != last()">

然后一切都将按需要工作。

答案 2 :(得分:1)

看来您可以将其简化为

<xsl:variable name="list_of_corresp_events">
   <xsl:value-of select="for $t in tokenize($paramCorrespdocs,'~') document(concat($paramSaxondatapath, $))/(key('correspkey',$correspid))/@xml:id" separator=", "/>
</xsl:variable>

或带有string-join

<xsl:variable name="list_of_corresp_events" select="string-join(for $t in tokenize($paramCorrespdocs,'~') document(concat($paramSaxondatapath, $))/(key('correspkey',$correspid))/@xml:id, ', ')"/>