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

如何通过XSLT使新DITA结构中的audience属性传递至输出?

问题描述

我之前成功更新过XSLT脚本,能把audience属性添加到输出里,但现在需要调整输出的显示方式,却没法让转换脚本正确获取该属性了。

原输入与原脚本

原输入内容:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE bookmap PUBLIC "-//OASIS//DTD DITA BookMap//EN" "bookmap.dtd" []>
<bookmap>
<topicgroup>
            <topichead navtitle="Arkansas Property and Casualty Adjuster Law" locktitle="yes" audience="Arkansas">
                <topicgroup>
                    <mapref href="Qbank/maps/Adj_Unit_AR.ditamap" format="ditamap"/>
                </topicgroup>
            </topichead>
        </topicgroup>
</bookmap>

原脚本相关部分:

<xsl:template match="*[contains(@class,' mapgroup-d/topichead ')]">
        <topichead>
            <xsl:attribute name="navtitle">
                <xsl:value-of select="@navtitle"/>
            </xsl:attribute>
             
            <xsl:choose>
                <xsl:when test="@audience">
                    <xsl:attribute name="audience">
                        <xsl:value-of select="@audience"/>  
                    </xsl:attribute>
                </xsl:when>
                <xsl:otherwise /> 
            </xsl:choose>
      </topichead>
</xsl:template>

新输入与问题脚本

现在输入结构变了,audience属性移到了<chapter>标签上:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE bookmap PUBLIC "-//OASIS//DTD DITA BookMap//EN" "bookmap.dtd" []>
<bookmap>
<chapter navtitle="Alabama Property and Casualty Adjuster Law" locktitle="yes" audience="Alabama">
        <topicgroup>           
                <topicgroup>
                    <mapref href="Qbank/maps/Adj_Unit_AL.ditamap" format="ditamap"/>
                </topicgroup>            
        </topicgroup>
    </chapter>
</bookmap>

我尝试了下面的脚本,但没法提取到audience属性,请问哪里出错了?

<xsl:template match="*[contains(@class,' mapgroup-d/topichead ')]">
        <topichead>
            <xsl:attribute name="navtitle">
                <xsl:value-of select="@navtitle"/>
            </xsl:attribute>
             
            <xsl:choose>
                <xsl:when test="bookmap/chapter/@audience">
                    <xsl:attribute name="audience">
                        <xsl:value-of select="@audience"/>  
                    </xsl:attribute>
                </xsl:when>
                <xsl:otherwise /> 
            </xsl:choose>
      </topichead>
</xsl:template>

问题分析与修正

你的脚本有两个核心错误:

  1. 模板匹配目标不匹配新输入:原模板匹配的是topichead元素,但新输入里根本不存在topichead节点,这个模板根本不会被触发,自然无法处理属性。
  2. XPath选择逻辑错误:即使模板能触发,bookmap/chapter/@audience是错误的路径写法(缺少根节点前缀/),且xsl:value-of里的@audience还是取当前节点的属性,而当前节点(如果是topichead)并没有这个属性,应该指向chapter节点的属性。

修正后的脚本

假设你需要把<chapter>的audience属性转移到输出的<topichead>中,正确的脚本如下:

<xsl:template match="*[contains(@class,' bookmap/chapter ')]">
    <topichead>
        <!-- 复制chapter的navtitle属性 -->
        <xsl:attribute name="navtitle">
            <xsl:value-of select="@navtitle"/>
        </xsl:attribute>
        
        <!-- 提取并添加chapter的audience属性 -->
        <xsl:if test="@audience">
            <xsl:attribute name="audience">
                <xsl:value-of select="@audience"/>
            </xsl:attribute>
        </xsl:if>
        
        <!-- 保留原chapter下的子节点结构 -->
        <xsl:apply-templates/>
    </topichead>
</xsl:template>

补充说明

  • 用xsl:if替代xsl:choose更简洁,仅处理存在audience属性的情况。
  • 模板匹配目标改为chapter元素(通过DITA标准的class属性bookmap/chapter),这样才能捕获到带有audience属性的节点。
  • xsl:apply-templates用来处理chapter下的子节点,保证原结构里的topicgroup等内容能正常转换。

如果你的场景需要在现有topichead模板中获取上层chapter的属性,可将XPath调整为ancestor::*[contains(@class,' bookmap/chapter ')]/@audience,但前提是topichead确实处于chapter的层级之下。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 03:40:21