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

如何根据XML内容选择导入对应的XSL样式表?

问题分析与解决方案

你遇到的转换失败,核心原因是XSLT的<xsl:import>属于静态编译指令——它必须在样式表的编译阶段就确定要导入的资源,不能放在运行时执行的模板(比如<xsl:template match="/">)或条件判断(<xsl:choose>)内部,运行时的节点值无法影响静态导入的逻辑。

下面是几种可行的替代方案:


方案1:预导入所有样式表,动态调用对应模板(兼容XSLT 1.0)

先静态导入所有可能的设施样式表,再根据XML中的Source值,调用对应样式表中定义的专属主模板。

主样式表代码:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- 提前导入所有子样式表 -->
  <xsl:import href="Stylesheet for Facility A.xml"/>
  <xsl:import href="Stylesheet for Facility B.xml"/>

  <xsl:template match="/">
    <!-- 根据Source值匹配对应节点,触发模板调用 -->
    <xsl:apply-templates select="Root/Source"/>
  </xsl:template>

  <!-- 匹配Facility A,调用子样式表的主模板 -->
  <xsl:template match="Source[text()='Facility A']">
    <xsl:call-template name="FacilityA-Main"/>
  </xsl:template>

  <!-- 匹配Facility B,调用子样式表的主模板 -->
  <xsl:template match="Source[text()='Facility B']">
    <xsl:call-template name="FacilityB-Main"/>
  </xsl:template>
</xsl:stylesheet>

要求每个子样式表(比如Stylesheet for Facility A.xml)必须定义一个唯一名称的主模板,示例:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template name="FacilityA-Main">
    <!-- 这里写Facility A的转换逻辑 -->
  </xsl:template>
</xsl:stylesheet>

方案2:使用静态参数指定导入(兼容XSLT 2.0+,需处理器支持)

如果你的XSLT处理器支持静态参数(比如Saxon),可以通过静态参数传递设施名称,直接在编译阶段确定要导入的样式表。

主样式表代码:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- 定义静态参数,值来自XML的Source节点 -->
  <xsl:param name="facility-name" select="/Root/Source/text()" static="yes"/>

  <!-- 用静态参数拼接样式表路径,实现条件导入 -->
  <xsl:import href="Stylesheet for {$facility-name}.xml"/>

  <xsl:template match="/">
    <xsl:apply-templates/>
  </xsl:template>
</xsl:stylesheet>

方案3:动态加载样式表文档(兼容XSLT 1.0/2.0)

通过document()函数动态加载对应设施的样式表文档,再调用其中的模板逻辑。

主样式表代码:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">
    <!-- 拼接目标样式表的路径 -->
    <xsl:variable name="stylesheet-path">
      <xsl:text>Stylesheet for </xsl:text>
      <xsl:value-of select="Root/Source/text()"/>
      <xsl:text>.xml</xsl:text>
    </xsl:variable>

    <!-- 动态加载样式表文档 -->
    <xsl:variable name="target-stylesheet" select="document($stylesheet-path)"/>

    <!-- 调用样式表中的主模板 -->
    <xsl:call-template name="Main" select="$target-stylesheet"/>
  </xsl:template>
</xsl:stylesheet>

同样要求子样式表定义统一名称的主模板(比如Main),确保可以被正确调用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 23:55:19