使用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的限制,需要借助扩展函数将排序后的结果树片段转为节点集:
- 先定义排序后的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> - 在样式表根节点添加扩展命名空间:
xmlns:exsl="http://exslt.org/common" - 循环中使用转换后的节点集:
<td><xsl:value-of select="exsl:node-set($sorted-wordlist2)/word[$current-pos]"/></td>
- 先定义排序后的wordlist2变量:
内容的提问来源于stack exchange,提问作者Krulle Bandhagen
相关产品推荐
相关产品推荐

