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

XSLT嵌套循环问题:section与para节点嵌套错误修复求助

Fixing XML Section Nesting and Para Node Assignment

Hey there, let's tackle your XML transformation issue. The core problem here is that your original XSLT doesn't handle the para nodes at all (they're left floating outside sections) and the hardcoded level-specific templates don't properly capture all the content that should be nested under each section.

Problem Breakdown

Your goal is to:

  • Nest lower-level section nodes (e.g., level="2" under level="1", level="3" under level="2")
  • Attach all subsequent sibling para nodes to the preceding section until the next section of the same or higher level comes along

The original XSLT misses the para handling entirely, and its rigid per-level templates can't dynamically associate sections with their related content.

Solution XSLT

We'll use XSLT 2.0's <xsl:for-each-group> for grouping content and recursive templates to handle dynamic nesting. This approach automatically captures both child sections and related para nodes:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" encoding="UTF-8" indent="yes" omit-xml-declaration="no"/>

    <!-- Identity template: copy all nodes/attributes unless overridden -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- Handle the top-level section (level="1") -->
    <xsl:template match="section[@level='1']">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
            <!-- Group all following siblings until a section of same or higher level -->
            <xsl:for-each-group select="following-sibling::*" group-starting-with="section[@level &lt;= current()/@level]">
                <!-- Only process direct child sections (level = parent +1) -->
                <xsl:if test="current-grouping-key()/@level = current()/@level + 1">
                    <xsl:apply-templates select="current-grouping-key()" mode="nested">
                        <xsl:with-param name="parent-level" select="current()/@level"/>
                    </xsl:apply-templates>
                </xsl:if>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>

    <!-- Recursive template for nested sections -->
    <xsl:template match="section" mode="nested">
        <xsl:param name="parent-level"/>
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
            <!-- Group content until next section of same or higher parent level -->
            <xsl:for-each-group select="following-sibling::*" group-starting-with="section[@level &lt;= $parent-level + 1]">
                <xsl:choose>
                    <!-- If it's a child section (level = parent +2), recurse -->
                    <xsl:when test="current-grouping-key()/@level = $parent-level + 2">
                        <xsl:apply-templates select="current-grouping-key()" mode="nested">
                            <xsl:with-param name="parent-level" select="$parent-level + 1"/>
                        </xsl:apply-templates>
                    </xsl:when>
                    <!-- Otherwise, copy all para nodes in the group -->
                    <xsl:otherwise>
                        <xsl:apply-templates select="current-group()"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>

    <!-- Suppress original flat sections to avoid duplicates -->
    <xsl:template match="section[@level != '1']"/>
</xsl:stylesheet>

How This Works

  1. Identity Template: Preserves all base XML structure unless we explicitly override a node's handling.
  2. Top-Level Section Handling: Matches your level="1" section, then groups its following siblings to find direct child sections (level="2").
  3. Recursive Nesting: The mode="nested" template recursively processes each child section, grouping its subsequent content to attach related para nodes and nested child sections (e.g., level="3" under level="2").
  4. Suppress Duplicates: The final template hides the original flat non-level-1 sections so they don't appear twice in the output.

Result

When you run this XSLT on your input XML, it will produce exactly the nested structure you want: all lower-level sections are nested under their parent sections, and every para node is attached to the correct preceding section.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 03:59:42