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

XSLT group-by分组时apply-templates如何获取父标签属性值

XSLT分组场景下节点属性获取及多文件输出方案

现有代码问题

  • 分组规则错误:需求是按docum的year属性分组(同一年份的文档生成到同一个章节页),原有代码写为group-by="@month",分组逻辑完全不匹配。
  • 上下文理解偏差:for-each-group循环内的顶层上下文是当前分组的第一个节点,原有代码仅在页面根节点写了一组<h1>/<h2>,但分组内每个文档都需要单独输出标题+内容的块结构;另外处理current-group()内的节点时,每个docum节点本身就携带year、month属性,直接在匹配模板中取当前节点属性即可,无需额外向上查找父标签。
  • 目录和文件命名逻辑错误:预期目录只有3个链接对应3个分组页,原有代码遍历所有docum生成5个链接,且用generate-id()生成随机文件名,和预期的1.htm/2.htm/3.htm命名规则不匹配。

正确实现代码(XSLT 2.0+ 适用)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:template match="root">
        <xsl:apply-templates select="main" mode="toc" />
        <xsl:apply-templates select="main" mode="chapter" />
    </xsl:template>

    <!-- 生成目录页toc.htm -->
    <xsl:template match="main" mode="toc">
        <xsl:result-document href="toc.htm" method="html">
            <html>
                <body>
                    <div>
                        <xsl:for-each-group select="docum" group-by="@year">
                            <!-- 按年份倒序,匹配预期的2022→2021→2020顺序 -->
                            <xsl:sort select="@year" order="descending" data-type="number"/>
                            <div>
                                <a href="{position()}.htm">
                                    <xsl:value-of select="current-group()[1]/@year"/>_<xsl:value-of select="current-group()[1]/@month"/>
                                </a>
                            </div>
                        </xsl:for-each-group>
                    </div>
                </body>
            </html>
        </xsl:result-document>
    </xsl:template>

    <!-- 生成各章节页 -->
    <xsl:template match="main" mode="chapter">
        <xsl:for-each-group select="docum" group-by="@year">
            <xsl:sort select="@year" order="descending" data-type="number"/>
            <!-- 用分组序号生成文件名,和目录链接一一对应 -->
            <xsl:result-document href="{position()}.htm" method="html">
                <html>
                    <body>
                        <xsl:apply-templates select="current-group()"/>
                    </body>
                </html>
            </xsl:result-document>
        </xsl:for-each-group>
    </xsl:template>

    <!-- 处理单个docum节点,输出内容块 -->
    <xsl:template match="docum">
        <div>
            <!-- 直接取当前节点自身属性即可 -->
            <h1><xsl:value-of select="@year"/></h1>
            <h2><xsl:value-of select="@month"/></h2>
            <xsl:value-of select="."/>
        </div>
    </xsl:template>
</xsl:stylesheet>

关键知识点

  • apply-templates处理current-group()内节点时,每个被处理的节点会成为匹配模板的当前上下文节点,直接通过@属性名即可获取节点自身属性,不需要额外查找父级。
  • 如果需要在子节点处理逻辑中用到分组级的公共值(比如分组键、分组序号),可以在调用apply-templates时通过参数传递,示例写法:
<!-- 调用模板时传参 -->
<xsl:apply-templates select="current-group()">
    <xsl:with-param name="groupKey" select="current-grouping-key()"/>
    <xsl:with-param name="pageNo" select="position()"/>
</xsl:apply-templates>

<!-- 匹配模板中接收参数 -->
<xsl:template match="docum">
    <xsl:param name="groupKey"/>
    <xsl:param name="pageNo"/>
    <!-- 后续可直接通过$groupKey、$pageNo调用传入的值 -->
</xsl:template>

注:你给出的预期输出中存在两处笔误:toc第三个链接文本写为2022_2020.11、3.htm第二个块的h2写为2020.11,上述代码按正常业务逻辑修正为对应年份和月份值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 04:39:35