XSLT实现XML转HTML:生成导航目录与内部链接问题求助
解决XML到HTML的XSLT转换问题:生成目录与内部链接
需要实现两个核心功能:
- 生成带章节跳转链接的独立章节目录列表
- 将XML中的编号引用
<ref>转换为指向对应章节的内部链接
输入XML片段
<content> <section> <num value="35">35. First title</num> <line>Text goes here.</line> </section> <section> <num value="36">36. Second title</num> <line>More text <ref>35</ref> here.</line> </section> </content>
期望输出HTML
<body> <toc> <tocitem><a href="#35">35. First title</a></tocitem> <tocitem><a href="#36">36. Second title</a></tocitem> </toc> <content> <section> <num><a id="35">35. First title</a></num> <p>Text goes here.</p> </section> <section> <num><a id="36">36. Second title</a></num> <p>More text <ref><a href="#35">35</a></ref> here.</p> </section> </content> </body>
现有XSLT代码(存在问题)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" encoding="utf-8" indent="yes"> <xsl:template match="/"> <html> <body> <toc> <xsl:apply-templates select="num" mode="links"/> </toc> <content> <xsl:apply-templates /> </content> </body> </html> </xsl:template> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates /> </xsl:copy> </xsl:template> <xsl:template match="num" mode="toc"> <tocitem> <xsl:value-of select="."/> </tocitem> </xsl:template> </xsl:stylesheet>
现有代码问题:
- 目录生成时节点选择路径错误,导致目录为空
- 未给章节标题添加锚点id
- 未处理
<ref>节点生成内部链接
修正后的完整XSLT代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" encoding="utf-8" indent="yes"> <!-- 根节点模板:构建HTML结构,生成目录和内容 --> <xsl:template match="/"> <html> <body> <toc> <!-- 正确定位所有section下的num节点,使用toc模式生成目录项 --> <xsl:apply-templates select="content/section/num" mode="toc"/> </toc> <content> <xsl:apply-templates /> </content> </body> </html> </xsl:template> <!-- 恒等转换模板:默认复制所有节点和属性 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates /> </xsl:copy> </xsl:template> <!-- 目录模式:生成带跳转链接的目录项 --> <xsl:template match="num" mode="toc"> <tocitem> <a href="#{@value}"> <xsl:value-of select="."/> </a> </tocitem> </xsl:template> <!-- 处理章节标题:添加锚点id --> <xsl:template match="num"> <num> <a id="{@value}"> <xsl:value-of select="."/> </a> </num> </xsl:template> <!-- 处理line节点:转换为p标签 --> <xsl:template match="line"> <p> <xsl:apply-templates /> </p> </xsl:template> <!-- 处理ref节点:生成指向对应章节的内部链接 --> <xsl:template match="ref"> <ref> <a href="#{.}"> <xsl:value-of select="."/> </a> </ref> </xsl:template> </xsl:stylesheet>
关键修改说明
- 修复目录节点选择:将
select="num"改为select="content/section/num",确保能遍历到所有章节标题;统一使用toc模式生成目录项,每个项生成带href="#编号"的链接。 - 添加章节锚点:重写
num节点模板,将标题内容包裹在带id="编号"的<a>标签中,作为跳转锚点。 - 转换
<line>为<p>:匹配line节点,将其转换为HTML的<p>标签,符合HTML语义。 - 处理
<ref>链接:新增ref节点模板,根据引用的编号生成指向对应锚点的<a>标签,实现内部跳转。
内容的提问来源于stack exchange,提问作者lordmurf
相关产品推荐
相关产品推荐

