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

咨询xsl:result-document合法字符范围及查询来源

问题描述

我正在使用XSLT将XML转换为一系列HTML文件,使用如下代码指定输出文档:

<xsl:result-document method="html" encoding="UTF-8" href="{$BaseFolder}{$filename}.html">
                <html>
                    ...
                </html>

部分文档转换失败,报错信息为Invalid syntax for relative URI。经排查,问题出在$filename变量,其值有时包含非法字符。为此我编写了清理文件名的模板:

<xsl:template name="make-safe-filename">
        <xsl:param name="input"/>
        <!--Remove illegal Windows filename characters-->
        <xsl:variable name="step1" select="replace($input, '[\\:*?&quot;&lt;&gt;|]', '')"/>
        <!--remove path separators-->
        <xsl:variable name="step2" select="replace($step1, '/', '-')"/>
        <!-- Replace [ and ] with ( and ) -->
        <xsl:variable name="step3" select="translate($step2, '[]', '()')"/>
        
        <!--Collapse whitespace-->
        <xsl:variable name="step4" select="normalize-space($step3)"/>
        
        <xsl:value-of select="$step4"/>
    </xsl:template>

令我意外的是,需过滤掉[]和(),而这些字符在Windows文件名中是合法的。我尝试查找xsl:result-document的合法/非法字符列表但未成功,RFC 2396仅提及存在‘受限字符集’却未明确具体范围。请问该信息可从何处获取?

回答

为什么[]()会触发URI错误?

xsl:result-document的href属性遵循URI语法规则,而非单纯的操作系统文件名规则。在URI标准(RFC 3986)中,[和]属于保留字符,专门用于包裹IPv6地址,未经编码直接使用会触发语法错误。而()虽属于“未保留字符”,但部分XSLT处理器可能对URI解析更严格,或()出现在路径段的特殊位置(如开头/结尾)时引发了兼容问题。

合法字符的参考依据

  1. XSLT规范与URI标准:XSLT 2.0及后续版本明确要求xsl:result-document的href符合RFC 3986的URI语法,该标准清晰定义了字符范围:
    • 可直接使用的未保留字符:A-Za-z0-9-._~
    • 有特殊含义的保留字符::/?#[]@!$&'()*+,;=,若要作为普通字符使用,必须进行百分编码(如[编码为%5B,]编码为%5D)
  2. XSLT处理器文档:不同处理器(如Saxon、Xalan)可能有额外限制或扩展逻辑,建议查看你使用的处理器官方文档,里面会明确URI处理的细节和字符要求。
  3. 更可靠的自动处理方式:无需手动替换字符,可使用XSLT内置的encode-for-uri()函数,它会自动按照RFC 3986规则对非法字符进行百分编码,示例:
    <xsl:result-document href="{$BaseFolder}{encode-for-uri($filename)}.html">
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 14:19:52