如何在XSLT中实现术语混排、互引锚点的词库构建?
XSLT词库重构方案(满足混合排序+双显非首选+字母导航)
核心思路
先统一收集所有术语(首选@tag='1'、非首选@tag='2'),建立非首选到首选的映射关系,按字母排序后生成主列表,同时处理非首选的双重呈现逻辑,最后生成字母导航锚点。
关键XSLT代码实现
假设你的XML结构类似(示例结构):
<thesaurus> <term tag="1" id="term1">Apple</term> <term tag="2" ref="term1">Malus domestica</term> <term tag="1" id="term2">Banana</term> <term tag="2" ref="term2">Musa paradisiaca</term> </thesaurus>
对应的XSLT修改方案:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" encoding="UTF-8" indent="yes"/> <!-- 建立非首选术语到首选术语的映射:key为首选ID,值为所有关联非首选 --> <xsl:key name="non-preferred-by-preferred" match="term[@tag='2']" use="@ref"/> <!-- 建立所有术语的首字母分组key --> <xsl:key name="term-by-first-letter" match="term" use="translate(substring(.,1,1), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"/> <!-- 获取所有唯一的首字母(小写去重排序) --> <xsl:variable name="unique-letters" select="distinct-values(translate(substring(term,1,1), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'))"/> <xsl:variable name="sorted-letters" select="$unique-letters[not(.=preceding::*)][order by .]"/> <xsl:template match="/"> <html> <head> <style> .nav { margin-bottom: 20px; } .nav a { margin: 0 5px; text-decoration: none; } .preferred { font-weight: bold; } .non-preferred { margin-left: 20px; color: #666; } .non-preferred-link { font-style: italic; } </style> </head> <body> <!-- 字母导航栏 --> <div class="nav"> <xsl:for-each select="$sorted-letters"> <a href="#letter-{.}"><xsl:value-of select="upper-case(.)"/></a> </xsl:for-each> </div> <!-- 主术语列表 --> <div class="thesaurus-list"> <!-- 按首字母分组遍历 --> <xsl:for-each select="$sorted-letters"> <xsl:variable name="current-letter" select="."/> <h3 id="letter-{$current-letter}"><xsl:value-of select="upper-case($current-letter)"/></h3> <!-- 提取当前首字母下的所有术语,按文本字母排序 --> <xsl:for-each select="key('term-by-first-letter', $current-letter)"> <xsl:sort select="translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"/> <!-- 处理首选术语:显示本身 + 关联非首选 --> <xsl:if test="@tag='1'"> <div class="preferred" id="term-{@id}"> <xsl:value-of select="."/> <!-- 显示关联的非首选术语 --> <xsl:if test="key('non-preferred-by-preferred', @id)"> <div class="non-preferred-list"> <xsl:for-each select="key('non-preferred-by-preferred', @id)"> <div class="non-preferred">→ <xsl:value-of select="."/></div> </xsl:for-each> </div> </xsl:if> </div> </xsl:if> <!-- 处理非首选术语:单独显示并链接到首选 --> <xsl:if test="@tag='2'"> <div class="non-preferred-link"> <xsl:value-of select="."/> → <a href="#term-{@ref}"><xsl:value-of select="//term[@id=@ref]"/></a> </div> </xsl:if> </xsl:for-each> </xsl:for-each> </div> </body> </html> </xsl:template> </xsl:stylesheet>
方案说明
- 映射关系建立:用
<xsl:key>分别关联非首选到首选,以及按首字母分组所有术语,解决关联查找和分组问题。 - 字母导航:提取所有术语首字母去重排序,生成带锚点的导航链接,点击直接跳转到对应首字母的术语组。
- 混合排序:所有术语按首字母分组后,内部再按文本字母排序,实现首选和非首选的混合展示。
- 非首选双重呈现:
- 作为独立条目显示,斜体样式,并链接到对应的首选术语锚点;
- 在关联的首选术语下方,作为附属项列出。
- 样式优化:通过内嵌CSS区分首选、非首选的视觉样式,提升可读性。
内容的提问来源于stack exchange,提问作者E-Flo
相关产品推荐
相关产品推荐

