如何用XSLT(xsltproc)实现多语言代码语法高亮并规避XML冲突
方案一:使用XSLTHL实现语法高亮
XSLTHL是专为XSLT设计的语法高亮库,xsltproc支持通过扩展调用它,具体步骤如下:
准备依赖
- 下载XSLTHL的jar包(如xslthl-2.1.2.jar)及配套的XSL模板文件
xslthl.xsl - 配置环境变量
CLASSPATH,确保包含XSLTHL的jar包,让xsltproc能识别Java扩展
- 下载XSLTHL的jar包(如xslthl-2.1.2.jar)及配套的XSL模板文件
编写核心XSLT模板
匹配带language属性的<code>标签,调用XSLTHL模板处理代码内容,输出带CSS类的HTML元素:<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xslthl="http://xslthl.sf.net" exclude-result-prefixes="xslthl"> <!-- 引入XSLTHL核心模板 --> <xsl:import href="xslthl.xsl"/> <!-- 处理带语言属性的<code>标签 --> <xsl:template match="code[@language]"> <pre> <xsl:call-template name="xslthl:highlight"> <xsl:with-param name="language" select="@language"/> <xsl:with-param name="content" select="text()"/> </xsl:call-template> </pre> </xsl:template> <!-- 安全输出文本,避免XML特殊字符解析异常 --> <xsl:template match="text()"> <xsl:value-of select="." disable-output-escaping="no"/> </xsl:template> </xsl:stylesheet>配置支持的语言
编辑xslthl-config.xml,启用需要的语言高亮规则:<xslthl-config> <language name="c" class="net.sf.xslthl.highlighters.CHighlighter"/> <language name="ada" class="net.sf.xslthl.highlighters.AdaHighlighter"/> <language name="latex" class="net.sf.xslthl.highlighters.TeXHighlighter"/> <!-- 按需添加其他语言 --> </xslthl-config>执行转换
用xsltproc调用模板,指定XSLTHL配置路径:xsltproc --extension java --param xslthl.config.path "'xslthl-config.xml'" your-transform.xsl your-source.xml添加CSS样式
生成的HTML会包含.keyword、.string、.comment等类,编写对应CSS实现高亮:.keyword { color: #0000FF; font-weight: bold; } .string { color: #008000; } .comment { color: #808080; font-style: italic; } /* 根据XSLTHL输出的类名补充样式 */
方案二:结合Pygments与XSLT
Pygments是功能全面的语法高亮工具,可通过XSLT调用外部Python脚本实现代码处理:
编写Pygments调用脚本
创建pygments-highlight.py,接收语言参数和代码内容,输出带CSS类的HTML片段:#!/usr/bin/env python3 import sys from pygments import highlight from pygments.lexers import get_lexer_by_name from pygments.formatters import HtmlFormatter if __name__ == "__main__": if len(sys.argv) != 3: sys.exit(1) language = sys.argv[1] code = sys.stdin.read() try: lexer = get_lexer_by_name(language) formatter = HtmlFormatter(nowrap=True) print(highlight(code, lexer, formatter)) except Exception: print(code) # 出错时输出原始代码给脚本添加可执行权限:
chmod +x pygments-highlight.py编写XSLT模板调用外部脚本
利用xsltproc的外部程序调用能力,处理<code>标签内容:<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="code[@language]"> <pre> <xsl:variable name="lang" select="@language"/> <xsl:variable name="code-content" select="text()"/> <!-- 调用外部Python脚本生成高亮代码 --> <xsl:variable name="highlighted" select="document(concat('|./pygments-highlight.py ', $lang))"> <xsl:param name="input" select="$code-content"/> </xsl:variable> <xsl:copy-of select="$highlighted"/> </pre> </xsl:template> <!-- 处理XML特殊字符,避免解析冲突 --> <xsl:template match="text()"> <xsl:value-of select="." disable-output-escaping="no"/> </xsl:template> </xsl:stylesheet>执行转换
直接运行xsltproc命令:xsltproc your-transform.xsl your-source.xml生成Pygments默认CSS
用Pygments导出默认样式文件:pygmentize -S default -f css > pygments.css在生成的HTML中引入该CSS文件即可生效。
关键注意事项
- XML冲突解决:源文档中
<code>标签内的特殊字符(<、>、&)必须提前转义为<、>、&,否则xsltproc会将其解析为XML标签导致转换失败。可通过sed批量预处理:sed -i '/<code/ { :a; N; /<\/code>/! ba; s/</\</g; s/>/\>/g; s/&/\&/g; }' your-source.xml - 环境依赖检查:使用XSLTHL时确保xsltproc支持Java扩展;使用Pygments时需提前安装库(
pip install pygments),并确保系统允许xsltproc调用外部脚本。
内容的提问来源于stack exchange,提问作者fauve
相关产品推荐
相关产品推荐

