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

如何在DITA OT插件的XSLT中跨模板调用变量值

如何在DITA-OT XSLT中传递output-class变量到map根模板

要把set-output-class模板里计算好的output-class相关变量传递给匹配/*[df:class(., 'map/map')]的模板,有两种实用方案,我结合你的代码示例详细说明:

方案一:直接在map根模板中获取值(最简单)

既然目标模板是处理map根元素,你可以直接在该模板内部重用set-output-class里的逻辑来获取对应的输出类值,不需要修改原有set-output-class模板。

修改你的目标map模板,新增变量来获取值:

<xsl:template match="/*[df:class(., 'map/map')]">
  <xsl:param name="doDebug" as="xs:boolean" tunnel="yes" select="false()"/>
  
  <!-- 新增:获取当前map元素的output-class值,重用set-output-class里的逻辑 -->
  <xsl:variable name="map-output-class">
    <!-- 先调用get-output-class mode获取基础值 -->
    <xsl:apply-templates select="." mode="get-output-class"/>
    <!-- 如果需要包含draft修订的内容,加上set-output-class里的draft-revs逻辑 -->
    <xsl:if test="$DRAFT = 'yes'">
      <xsl:text> </xsl:text>
      <xsl:for-each select="*[contains(@class, ' ditaot-d/ditaval-startprop ')]/revprop">
        <xsl:value-of select="@val"/>
        <xsl:text> </xsl:text>
      </xsl:for-each>
    </xsl:if>
  </xsl:variable>
  
  <!-- 现在可以直接使用$map-output-class变量了 -->
  <xsl:message>Debug: Map output class is '<xsl:value-of select="normalize-space($map-output-class)"/>'</xsl:message>
  
  <xsl:variable name="effectiveCoverGraphicUri" as="xs:string">
    <xsl:apply-templates select="." mode="get-cover-graphic-uri"/>
  </xsl:variable>
  <!-- FIXME: Add mode to get effective front cover topic URI so we can generate <guide> entry for the cover page. Also provides extension point for synthesizing the cover if it's not explicit in the map. -->
  <xsl:apply-templates select="." mode="report-parameters">
    <xsl:with-param name="effectiveCoverGraphicUri" select="$effectiveCoverGraphicUri" as="xs:string" tunnel="yes"/>
    <!-- 如果需要传递给report-parameters模板,直接加参数即可 -->
    <xsl:with-param name="map-output-class" select="normalize-space($map-output-class)"/>
  </xsl:apply-templates>
  
  <!-- 你的后续原代码 -->
  <xsl:variable name="graphicMap" as="element()">
    <xsl:apply-templates select="." mode="generate-graphic-ma
<!-- 继续原逻辑即可 -->
</xsl:template>

这种方案的好处是不需要改动原有set-output-class模板,直接在需要的地方获取值,适合只在map根模板中使用该值的场景。

方案二:使用隧道参数传递(更灵活)

如果需要在多个模板之间传递这个值,或者set-output-class被多个地方调用时统一传递,XSLT的**隧道参数(tunnel parameters)**是最佳选择——它可以自动穿过中间模板,不需要每个中间模板都显式传递参数。

步骤1:修改set-output-class模板,添加隧道参数支持

<xsl:template match="*" mode="set-output-class">
  <xsl:param name="default"/>
  <!-- 新增:控制是否传递输出类的隧道参数,默认关闭 -->
  <xsl:param name="enable-output-class-tunnel" as="xs:boolean" tunnel="yes" select="false()"/>
  
  <xsl:variable name="output-class">
    <xsl:apply-templates select="." mode="get-output-class"/>
  </xsl:variable>
  <xsl:variable name="draft-revs">
    <!-- 原代码不变 -->
    <xsl:if test="$DRAFT = 'yes'">
      <xsl:for-each select="*[contains(@class, ' ditaot-d/ditaval-startprop ')]/revprop">
        <xsl:value-of select="@val"/>
        <xsl:text> </xsl:text>
      </xsl:for-each>
    </xsl:if>
  </xsl:variable>
  <xsl:variable name="using-output-class">
    <!-- 原代码不变 -->
    <xsl:choose>
      <xsl:when test="string-length(normalize-space($output-class)) &gt; 0"><xsl:value-of select="$output-class"/></xsl:when>
      <xsl:when test="string-length(normalize-space($default)) &gt; 0"><xsl:value-of select="$default"/></xsl:when>
    </xsl:choose>
    <xsl:if test="$draft-revs != ''">
      <xsl:text> </xsl:text>
      <xsl:value-of select="normalize-space($draft-revs)"/>
    </xsl:if>
  </xsl:variable>
  
  <!-- 新增:如果启用隧道参数,传递最终的using-output-class值 -->
  <xsl:if test="$enable-output-class-tunnel">
    <xsl:param name="resolved-output-class" select="normalize-space($using-output-class)" tunnel="yes"/>
  </xsl:if>
  
  <!-- 原代码的class属性输出部分不变 -->
  <xsl:variable name="ancestry">
    <xsl:if test="$PRESERVE-DITA-CLASS = 'yes'">
      <xsl:apply-templates select="." mode="get-element-ancestry"/>
    </xsl:if>
  </xsl:variable>
  <xsl:variable name="outputclass-attribute">
    <xsl:apply-templates select="@outputclass" mode="get-value-for-class"/>
  </xsl:variable>
  <xsl:if test="string-length(normalize-space(concat($outputclass-attribute, $using-output-class, $ancestry))) &gt; 0">
    <xsl:attribute name="class">
      <xsl:value-of select="$ancestry"/>
      <xsl:if test="string-length(normalize-space($ancestry)) &gt; 0 and string-length(normalize-space($using-output-class)) &gt; 0"><xsl:text> </xsl:text></xsl:if>
      <xsl:value-of select="$using-output-class"/>
      <xsl:if test="string-length(normalize-space(concat($ancestry, $using-output-class))) &gt; 0 and string-length(normalize-space($outputclass-attribute)) &gt; 0"><xsl:text> </xsl:text></xsl:if>
      <xsl:value-of select="$outputclass-attribute"/>
    </xsl:attribute>
  </xsl:if>
</xsl:template>

步骤2:修改目标map模板,启用隧道参数并接收值

<xsl:template match="/*[df:class(., 'map/map')]">
  <xsl:param name="doDebug" as="xs:boolean" tunnel="yes" select="false()"/>
  <!-- 接收隧道参数 -->
  <xsl:param name="resolved-output-class" tunnel="yes"/>
  
  <!-- 调用set-output-class时启用隧道参数传递 -->
  <xsl:apply-templates select="." mode="set-output-class">
    <xsl:with-param name="default" select="''"/>
    <xsl:with-param name="enable-output-class-tunnel" select="true()" tunnel="yes"/>
  </xsl:apply-templates>
  
  <!-- 使用传递过来的变量 -->
  <xsl:if test="$doDebug">
    <xsl:message>Debug: Resolved map output class: '<xsl:value-of select="$resolved-output-class"/>'</xsl:message>
  </xsl:if>
  
  <xsl:variable name="effectiveCoverGraphicUri" as="xs:string">
    <xsl:apply-templates select="." mode="get-cover-graphic-uri"/>
  </xsl:variable>
  
  <!-- 可以继续把值传递给其他模板 -->
  <xsl:apply-templates select="." mode="report-parameters">
    <xsl:with-param name="effectiveCoverGraphicUri" select="$effectiveCoverGraphicUri" as="xs:string" tunnel="yes"/>
    <xsl:with-param name="map-output-class" select="$resolved-output-class" tunnel="yes"/>
  </xsl:apply-templates>
  
  <!-- 你的后续原代码 -->
  <xsl:variable name="graphicMap" as="element()">
    <xsl:apply-templates select="." mode="generate-graphic-ma
<!-- 继续原逻辑 -->
</xsl:template>

这种方案适合需要在多个模板间传递该值的场景,隧道参数会自动跳过中间的模板调用,直接传递到接收的模板。

结合你提供的DITA示例,比如pubmap里的<mainpubtitle outputclass="book">,get-output-class会处理这个值,最终传递到map模板的变量里。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 09:08:56