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

XSLT 2+中实现Dependency Injection的惯用模式探讨

XSLT 中实现依赖注入的惯用模式探讨

本文所指的依赖注入是面向对象中传递代码指针的概念,在函数式编程(FP)中可通过高阶函数实现。在XSLT 2及以上版本中,常见以下几种实现方案:

  • 传递函数(遵循函数式编程范式)
  • 传递伪“模式”:通过传递显式构造的元素(或嵌入节点结构中的值)并进行匹配
    此外还有通过include/import静态注入代码的方式,更类似“模板方法”的静态组合模式。

核心问题:XSLT社区是否有实现依赖注入的惯用模式?
(若能像接口或类型类那样对注入内容进行打包会更理想,伪模式技术似乎可通过将“模式”嵌入其他元素实现,但直接使用函数则不太容易做到)

另外还有第三种方案:返回领域特定语言(DSL)并进行解释,不同上下文采用不同解释方式,类似“流水线”技术,但仅需注入细微逻辑时略显冗余。


通用XML输入

所有方案均基于以下XML输入执行:

<root>
    <foo/>
</root>

方案1:高阶函数(Higher Order Functions)

函数my:apply-function允许注入兼容签名的函数并执行,这是函数式编程的默认技术,示例代码如下:

<xsl:stylesheet version="3.0" 
    xmlns:my="my"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <!-- 定义接受函数参数的函数 -->
    <xsl:function name="my:apply-function" as="xs:integer">
        <xsl:param name="input" as="xs:integer"/>
        <xsl:param name="function" as="function(xs:integer) as xs:integer"/>
        <xsl:sequence select="$function($input)"/>
    </xsl:function>
    
    <!-- 定义可作为参数传递的示例函数 -->
    <xsl:function name="my:double" as="xs:integer">
        <xsl:param name="value" as="xs:integer"/>
        <xsl:sequence select="$value * 2"/>
    </xsl:function>
    
    <!-- 主模板 -->
    <xsl:template match="/">
        <result>
            <!-- 调用my:apply-function并传入my:double作为参数 -->
            <xsl:variable name="result" select="my:apply-function(5, my:double#1)"/>
            <doubled-value>
                <xsl:value-of select="$result"/>
            </doubled-value>
        </result>
    </xsl:template>
</xsl:stylesheet>

方案2:伪模式(Pseudo Modes)

该方案将选择逻辑编码在结构中并进行匹配,示例代码如下:

<xsl:stylesheet version="3.0" 
    xmlns:my="my"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <xsl:template mode="inject" match="Mode[@value = 'double']">
        <xsl:param name="value" as="xs:integer"/>
        <xsl:sequence select="$value * 2"/>
    </xsl:template>

    <xsl:template mode="inject" match="Mode[@value = 'treble']">
        <xsl:param name="value" as="xs:integer"/>
        <xsl:sequence select="$value * 3"/>
    </xsl:template>
    
    <!-- 主模板 -->
    <xsl:template match="/">
        <result>
            <doubled-value>
                <xsl:variable name="mode">
                    <Mode value='double'/>
                </xsl:variable>
                <xsl:apply-templates mode="inject" select="$mode">
                    <xsl:with-param name="value" select="5"/>
                </xsl:apply-templates>
            </doubled-value>
        </result>
    </xsl:template>
</xsl:stylesheet>

方案3:DSL/解释器(DSL/Interpreter)

该方案通过my:makeDSL返回XML编码的DSL,再由特定解释器处理,示例代码如下:

<xsl:stylesheet version="3.0" 
    xmlns:my="my"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <xsl:template mode="inject" match="Mode[@value = 'double']">
        <xsl:param name="value" as="xs:integer"/>
        <xsl:sequence select="$value * 2"/>
    </xsl:template>

    <xsl:template mode="inject" match="Mode[@value = 'treble']">
        <xsl:param name="value" as="xs:integer"/>
        <xsl:sequence select="$value * 3"/>
    </xsl:template>
    
    <xsl:template mode="double" match="nop"/>
        
    <xsl:template mode="double" match="inject">
        <xsl:sequence select="2 * @value"/>
    </xsl:template>
    
    <xsl:template mode="treble" match="nop"/>
    
    <xsl:template mode="treble" match="inject">
        <xsl:sequence select="3 * @value"/>
    </xsl:template>
    
    <!-- 主模板 -->
    <xsl:template match="/">
        <result>
            <doubled-value>
                <xsl:apply-templates mode="double" select="my:makeDSL(5)"/>
            </doubled-value>
        </result>
    </xsl:template>
    
    <xsl:function name="my:makeDSL">
        <xsl:param name="value"/>
        <nop/>
        <inject value="{$value}"/>
        <nop/>
    </xsl:function>
</xsl:stylesheet>

内容的提问来源于Stack Exchange,提问作者MrD at KookerellaLtd

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 14:10:34