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

如何为内存中的XSLT样式表设置SystemId?

XSLT中document('')在String类型StreamSource下的失效问题

我有一些XSLT样式表,通过匿名document('')函数实现内部查找表,示例代码如下:

<!-- example the lookup table data -->
<ref:data xmlns:ref="urn:inline-data">
    <phrasebook>
        <!-- English -->
        <lang code="en">
            <phrase code="USD_PREFIX">$ </phrase>
            <phrase code="GBP_PREFIX">£</phrase>
            <phrase code="EUR_PREFIX">€</phrase>
            <phrase code="JPY_PREFIX">¥</phrase>
        </lang>
        ...
    </phrasebook>
</ref:data>

<!-- the lookup table variable I can use elsewhere -->
<xsl:variable name="phrasebook" select="document('')/xsl:stylesheet/ref:data/phrasebook" xmlns:ref="urn:inline-data"/>

(注:ref命名空间实际在样式表定义中,此处为简洁单独列出)

问题是:使用String类型的StreamSource运行这类样式表会失败,但用File类型的StreamSource则正常。已知原因是Transformer无法获取StreamSource上未设置的SystemId,但对于内存中的String,应该将SystemId设置为什么值?


解决方案

当使用内存中的String作为XSLT源时,你需要给StreamSource设置一个虚拟的合法URI,这个值不需要对应真实存在的文件,只要符合URI格式规范即可。

核心逻辑

document('')的作用是加载当前样式表本身作为文档节点,XSLT处理器需要一个基准URI来解析这个相对引用(空字符串代表当前文档)。即使是内存中的字符串,设置虚拟SystemId就能让处理器完成这个解析逻辑。

具体设置示例

可以选择以下任意一种合法URI:

  • 虚拟文件路径:"file:///dummy.xsl"
  • URN格式:"urn:xslt:internal-stylesheet"
  • 甚至自定义的字符串格式(只要符合URI规范)

Java代码示例

String xsltContent = "...你的XSLT字符串内容...";
StreamSource xsltSource = new StreamSource(new StringReader(xsltContent));
// 设置虚拟SystemId
xsltSource.setSystemId("file:///dummy.xsl");

TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(xsltSource);
// 后续转换逻辑...

补充说明

  • 这个虚拟SystemId不需要指向真实文件,处理器仅用它确定当前样式表的基准URI,从而正确解析document('')引用。
  • 若不设置SystemId,处理器无法定位基准URI,会导致document('')无法找到样式表内部的ref:data节点,最终引发错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 23:02:47