XSLT转换XML到HTML时为<place>标签添加内嵌超链接的问题
XSLT转换XML地名标签为内嵌HTML超链接解决方案
问题核心原因
- 现有代码仅在根模板中使用
xsl:for-each全局遍历所有<place>标签,统一输出到转录文本末尾 - 没有为
<place>标签定义专用匹配模板,导致xsl:apply-templates处理文本内容时,仅输出<place>的文本内容,不会生成超链接 - 原有链接取值
{//place/@link}写法存在隐患://代表全文检索,会固定取文档中第一个<place>的link属性值
修改方案
步骤1:删除末尾集中输出链接的代码
移除根模板中以下代码块:
<!-- include WHG links --> <xsl:for-each select="//place"> <p>Genannte Orte im World Historical Gazetteer:</p> <a href="{//place/@link}" target="_blank"> <xsl:value-of select="."/> </a><br/> </xsl:for-each>
如果需要保留末尾地名汇总列表,可以单独调整位置,不要放在转录文本的<p>标签内。
步骤2:新增<place>标签专用匹配模板
在根模板外新增独立的<place>匹配模板,作用是遍历到文本中的<place>节点时,直接转换为对应超链接:
<xsl:template match="place"> <a href="{@link}" target="_blank"> <xsl:value-of select="."/> </a> </xsl:template>
修改后完整代码
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="html"/> <!-- 匹配place标签转换为超链接 --> <xsl:template match="place"> <a href="{@link}" target="_blank"> <xsl:value-of select="."/> </a> </xsl:template> <xsl:template match="/"> <!-- Jekyll statement --> --- <xsl:for-each select="source/metadata/digital_surrogate"> layout: page title: <xsl:value-of select="@filename"/> permalink: /<xsl:value-of select="@filename"/>/ exclude: true --- </xsl:for-each> <!-- Get transcription with links --> <div class="flex-container"> <div> <p><strong>Transkription:</strong></p> <p> <xsl:apply-templates select="//div"/> </p><br/> <!-- 如果需要保留末尾地名汇总列表,可以把原来的for-each放到这里 --> <!-- <p>Genannte Orte im World Historical Gazetteer:</p> <xsl:for-each select="//place"> <a href="{@link}" target="_blank"> <xsl:value-of select="."/> </a><br/> </xsl:for-each> --> </div> </div> </xsl:template> </xsl:stylesheet>
实现原理
XSLT的模板匹配机制会递归处理所有节点:
- 普通文本节点会按照内置默认模板原样输出
- 遇到
<place>节点时会命中自定义的模板,转换为超链接输出 - 其他结构节点的内容会按照原有顺序保留,地名链接会嵌入到原本出现的位置,完全符合预期输出效果。
内容的提问来源于stack exchange,提问作者OnceUponATime
相关产品推荐
相关产品推荐

