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

新手求助:基于指定条件的XSLT元素序列分组XML转换

XSLT分组转换XML解决方案

输入XML

<p style="Chap"></p>
<p style="ChapTitle"></p>
<p style="IntroHead">IntroHead</p>
<p style="IntroText">IntroText</p>
<p style="IntroText">IntroText</p>
<p style="IntroText">IntroText</p>
<p style="IntroLast">IntroLast</p>
<p style="Normal"></p>

<p style="Bullet">Bullet</p>
<p style="Bullet">Bullet</p>
<p style="Bullet">Bullet</p>
<p style="Bullet">Bullet</p>
<p style="Bullet">Bullet</p>
<p style="BulletLast">BulletLast</p>
<p style="Normal"></p>
<p style="Normal"></p>
<p style="Normal"></p>
<p style="Normal"></p>
<p style="Normal"></p>
<p style="Normal"></p>
<p style="Normal"></p>
<p style="Normal"></p>

期望输出XML

<p style="Chap"></p>
<p style="ChapTitle"></p>
<box>
<title>IntroHead</title>
<list>
<li>IntroText</li>
<li>IntroText</li>
<li>IntroText</li>
<li>IntroLast</li>
</list>
</box>
<p style="Normal"></p>

<list style="bullet">
<li>Bullet</li>
<li>Bullet</li>
<li>Bullet</li>
<li>Bullet</li>
<li>Bullet</li>
<li>BulletLast</li>
</list>
<p style="Normal"></p>
<p style="Normal"></p>
<p style="Normal"></p>
<p style="Normal"></p>
<p style="Normal"></p>
<p style="Normal"></p>
<p style="Normal"></p>
<p style="Normal"></p>

XSLT实现代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- 匹配根节点并遍历所有子节点 -->
    <xsl:template match="/">
        <xsl:for-each-group select="node()" group-adjacent="boolean(self::p[starts-with(@style, 'Intro') or starts-with(@style, 'Bullet')])">
            <!-- 直接输出非分组节点 -->
            <xsl:if test="not(current-grouping-key())">
                <xsl:copy-of select="current-group()"/>
            </xsl:if>
            <!-- 处理Intro系列分组 -->
            <xsl:if test="current-grouping-key() and current-group()[1]/@style='IntroHead'">
                <box>
                    <title>
                        <xsl:value-of select="current-group()[@style='IntroHead']"/>
                    </title>
                    <list>
                        <xsl:for-each select="current-group()[not(@style='IntroHead')]">
                            <li>
                                <xsl:value-of select="."/>
                            </li>
                        </xsl:for-each>
                    </list>
                </box>
            </xsl:if>
            <!-- 处理Bullet系列分组 -->
            <xsl:if test="current-grouping-key() and starts-with(current-group()[1]/@style, 'Bullet')">
                <list style="bullet">
                    <xsl:for-each select="current-group()">
                        <li>
                            <xsl:value-of select="."/>
                        </li>
                    </xsl:for-each>
                </list>
            </xsl:if>
        </xsl:for-each-group>
    </xsl:template>
</xsl:stylesheet>

关键逻辑说明

  • 用<xsl:for-each-group>的group-adjacent属性,把相邻的Intro/Bullet系列<p>元素归为一组
  • 非分组节点(如Chap、ChapTitle、Normal样式的<p>)直接原样输出
  • Intro组:外层套<box>,将IntroHead内容转为<title>,其余IntroText/IntroLast转为<list>下的<li>
  • Bullet组:外层套带style="bullet"的<list>,所有Bullet/BulletLast内容转为<li>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 15:45:36