You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在XSLT模板中忽略与<code>标签缩进对应数量的起始制表符?

解决XML中<code>标签代码缩进冲突的XSLT方案

实现思路

要搞定XML缩进和<code>内代码的冲突,分两步来:

  1. 先数清楚<code>起始标签前面有多少个制表符(记为n)
  2. 把<code>里每一行开头的n个制表符删掉,同时去掉内容首尾的换行符

完整XSLT代码

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- 匹配code标签并处理 -->
    <xsl:template match="code">
        <pre>
            <xsl:call-template name="clean-code-content">
                <!-- 传入code的文本内容,先清理首尾空白 -->
                <xsl:with-param name="raw-text" select="normalize-space(., ' \t')"/>
                <!-- 计算code标签前的制表符数量 -->
                <xsl:with-param name="indent-num">
                    <xsl:value-of select="string-length(substring-before(preceding-sibling::text()[1], '&#xA;'))"/>
                </xsl:with-param>
            </xsl:call-template>
        </pre>
    </xsl:template>

    <!-- 递归处理每一行,移除多余制表符 -->
    <xsl:template name="clean-code-content">
        <xsl:param name="raw-text"/>
        <xsl:param name="indent-num"/>
        <xsl:param name="line-break" select="'&#xA;'"/>
        
        <!-- 拆分出当前第一行 -->
        <xsl:variable name="current-line" select="substring-before(concat($raw-text, $line-break), $line-break)"/>
        <!-- 剩下的内容 -->
        <xsl:variable name="rest-text" select="substring-after($raw-text, $line-break)"/>

        <!-- 去掉当前行开头的n个制表符,输出结果 -->
        <xsl:value-of select="substring($current-line, $indent-num + 1)"/>
        
        <!-- 还有内容就继续递归处理下一行 -->
        <xsl:if test="$rest-text">
            <xsl:value-of select="$line-break"/>
            <xsl:call-template name="clean-code-content">
                <xsl:with-param name="raw-text" select="$rest-text"/>
                <xsl:with-param name="indent-num" select="$indent-num"/>
            </xsl:call-template>
        </xsl:if>
    </xsl:template>

    <!-- 默认模板:保留其他节点原样输出 -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

关键部分说明

  1. 计算缩进数:通过preceding-sibling::text()[1]拿到<code>标签前面的文本节点,统计换行前的字符长度(也就是制表符的数量)。
  2. 预处理文本:normalize-space(., ' \t')会保留换行符,同时把内容首尾的空白(包括换行)清掉,避免输出多余空行。
  3. 逐行清理:用递归的方式把文本拆成一行一行,每一行都从第n+1个字符开始截取,相当于去掉开头n个制表符。
  4. 兼容其他内容:最后的默认模板保证XML里其他标签和内容不受影响,正常输出。

测试效果

用你提供的XML示例跑这个XSLT,输出的<pre>内容会和预期完全一致——XML缩进带来的多余制表符被去掉了,代码本身的缩进格式还保留着。

内容的提问来源于stack exchange,提问作者fauve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 05:42:48