【问题标题】:XSLT 2.0 how to test for position() in tokenize() on outputXSLT 2.0 如何在输出的 tokenize() 中测试 position()
【发布时间】:2018-10-23 20:56:40
【问题描述】:

在 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() 应用于此的方法。

非常感谢。

【问题讨论】:

    标签: xslt xpath xslt-2.0


    【解决方案1】:

    改进@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() 涉及昂贵的前瞻。

    【讨论】:

      【解决方案2】:

      改变

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

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

      那么它应该可以按预期工作。

      【讨论】:

      • 作为解释,“.”是单个项目,即长度为 1 的序列,在长度为 1 的序列中,position()last() 将始终为 1,因此 position() != last() 将始终为 false,因此 .[position() != last()] 将始终为一个空序列,因此测试将评估为假。
      【解决方案3】:

      看来你可以把它简化为

      <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, ', ')"/>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-24
        • 1970-01-01
        • 1970-01-01
        • 2012-03-16
        • 1970-01-01
        • 2015-08-13
        相关资源
        最近更新 更多