You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用position()函数合并两个词表失效问题求助

词表合并时wordlist2词汇重复显示的问题

尝试将两个不同的词表合并生成词典,但通过Saxon运行时,每行都重复显示wordlist2中的第1个词。position()函数在循环中始终返回1,希望实现每行显示file A的1个词和file B的1个词,共10组词对。

相关XSLT代码

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="Lexicon" select="document('./Lexicon.xml')"/>
<xsl:variable name="URI1" select="$Lexicon/lexicon/wordlist1"/>
<xsl:variable name="URI2" select="$Lexicon/lexicon/wordlist2"/>
<xsl:variable name="URI3" select="$Lexicon/lexicon/icon"/>
<xsl:variable name="Wordlist1" select="document($URI1)"/>
<xsl:variable name="Wordlist2" select="document($URI2)"/>
<xsl:variable name="Icon" select="document($URI3)"/>
<xsl:template match="/">
    <html>
      <body>
      <xsl:copy-of select="$Icon"/>
        <table border="1">
          <tr bgcolor="#9acd32">
          <td colspan="2">Lexicon from <xsl:value-of select="document($URI1)/wordlist/@lang"/> to <xsl:value-of select="document($URI2)/wordlist/@lang"/></td>
          </tr>
          <xsl:for-each select="$Wordlist1/wordlist/word">
          <xsl:sort select="."/>
            <tr>
              <td><xsl:value-of select="."/></td>
              <td><xsl:value-of select="$Wordlist2/wordlist/word[position()]"/></td>
            </tr>
          </xsl:for-each>
        </table>
      </body>
    </html>
  </xsl:template>
 </xsl:stylesheet>

问题原因

position()函数的上下文错误。在$Wordlist2/wordlist/word[position()]表达式中,position()是针对$Wordlist2/wordlist/word这个节点集的遍历上下文,而非<xsl:for-each>循环的当前迭代位置,因此每次都会匹配到wordlist2的第一个词。

修复方案

在<xsl:for-each>循环内部,先将当前迭代的位置存入变量,再用该变量索引wordlist2的对应位置:

修改后的循环代码:

<xsl:for-each select="$Wordlist1/wordlist/word">
  <xsl:sort select="."/>
  <!-- 保存当前循环的位置 -->
  <xsl:variable name="current-pos" select="position()"/>
  <tr>
    <td><xsl:value-of select="."/></td>
    <!-- 使用变量获取对应位置的wordlist2词汇 -->
    <td><xsl:value-of select="$Wordlist2/wordlist/word[$current-pos]"/></td>
  </tr>
</xsl:for-each>

额外优化建议

  • 若要限制仅生成10组词对,可修改<xsl:for-each>的选择表达式,同时确保两个词表都至少有10个词:
    <xsl:for-each select="$Wordlist1/wordlist/word[position() <= 10]">
    
  • 如果你需要wordlist2也同步按词汇排序,由于XSLT 1.0的限制,需要借助扩展函数将排序后的结果树片段转为节点集:
    1. 先定义排序后的wordlist2变量:
      <xsl:variable name="sorted-wordlist2">
        <xsl:for-each select="$Wordlist2/wordlist/word">
          <xsl:sort select="."/>
          <xsl:copy-of select="."/>
        </xsl:for-each>
      </xsl:variable>
      
    2. 在样式表根节点添加扩展命名空间:
      xmlns:exsl="http://exslt.org/common"
      
    3. 循环中使用转换后的节点集:
      <td><xsl:value-of select="exsl:node-set($sorted-wordlist2)/word[$current-pos]"/></td>
      

内容的提问来源于stack exchange,提问作者Krulle Bandhagen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 05:28:12