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

如何使用XSLT将<p>标签内的元素与文本拆分至独立<p>标签?

需求:拆分

标签内的内容为独立元素

需要实现XSLT转换,将

标签内的子内容按原有顺序拆分:连续的文本及内联标签(如、)放入独立的

标签,块级元素(如)直接移出

,确保整体顺序不变。

输入示例

<kk><p id="p_aj3uga5iqfuzmmw"> Some text is here
        <table outputclass="ruled" id="ko4xjv6txx">
            <tgroup cols="2" id="67dc15u6ud">
                <colspec colname="c1" colnum="1" colwidth="40" id="jc204r3bna"/>
                <colspec colname="c2" colnum="2" colwidth="60" id="o79df53wog"/>
                <thead id="kih5dc7um1">
                    <row id="ve4ln370t8">
                        <entry id="yi4lwe9p51">head text is here</entry>
                        <entry id="dwl1ol06ju">head text is here</entry>
                    </row>
                </thead>
                <tbody id="62gug7qywr" class="- topic/tbody ">
                    <row id="7wdson97xv" class="- topic/row ">
                        <entry id="3at6ja8goj">text is here</entry>
                        <entry id="m33p8e0e9f">text is here</entry>
                    </row>
                </tbody>
            </tgroup>
        </table>
        <b id="nryvddsy5o"><i id="cs8atnkc9h">Component auditor responsibilities</i></b> some text here
    </p></kk>

期望输出

<kk><p id="p_aj3uga5iqfuzmmw"> Some text is here</p>
<table outputclass="ruled" id="ko4xjv6txx">
    <tgroup cols="2" id="67dc15u6ud">
        <colspec colname="c1" colnum="1" colwidth="40" id="jc204r3bna"/>
        <colspec colname="c2" colnum="2" colwidth="60" id="o79df53wog"/>
        <thead id="kih5dc7um1">
            <row id="ve4ln370t8">
                <entry id="yi4lwe9p51">head text is here</entry>
                <entry id="dwl1ol06ju">head text is here</entry>
            </row>
        </thead>
        <tbody id="62gug7qywr" class="- topic/tbody ">
            <row id="7wdson97xv" class="- topic/row ">
                <entry id="3at6ja8goj">text is here</entry>
                <entry id="m33p8e0e9f">text is here</entry>
            </row>
        </tbody>
    </tgroup>
</table>
<p><b id="nryvddsy5o"><i id="cs8atnkc9h">Component auditor responsibilities</i></b> some text here</p></kk>

现有XSLT代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
    exclude-result-prefixes="xs xd"
    version="2.0">
    
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="p">
        <xsl:choose>
            <xsl:when test="starts-with(., text())">
                <p><xsl:apply-templates select="text()[1] except table | text() | *"/></p>
            </xsl:when>
            <xsl:when test="table[1]">
                <xsl:apply-templates select="table[1]"/>        
            </xsl:when>
            <xsl:when test="*[1]">
                <xsl:apply-templates select="*[1]"/>        
            </xsl:when>
        </xsl:choose>
    </xsl:template>
    <xsl:template match="table">
        <table>
            <xsl:apply-templates select="@* | node()"/>
        </table>
    </xsl:template>
</xsl:stylesheet>

解决方案

核心思路是遍历

的所有子节点,将连续的文本节点和内联元素归为一组,生成新的

;**块级元素(如table)**直接输出,同时将原

的属性传递给第一个生成的新

。

以下是修正后的XSLT代码:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">

    <!-- 身份模板:复制所有未匹配的节点和属性 -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- 处理p标签 -->
    <xsl:template match="p">
        <!-- 按节点类型分组:块级元素单独一组,文本+内联元素为一组 -->
        <xsl:for-each-group select="node()" group-adjacent="boolean(self::table)">
            <xsl:choose>
                <!-- 块级元素组:直接输出 -->
                <xsl:when test="current-grouping-key()">
                    <xsl:apply-templates select="current-group()"/>
                </xsl:when>
                <!-- 文本+内联元素组:生成新的p标签 -->
                <xsl:otherwise>
                    <p>
                        <!-- 仅给第一个p标签添加原p的属性 -->
                        <xsl:if test="position() = 1">
                            <xsl:apply-templates select="../@*"/>
                        </xsl:if>
                        <xsl:apply-templates select="current-group()"/>
                    </p>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each-group>
    </xsl:template>

</xsl:stylesheet>

关键说明

  1. 分组逻辑:使用xsl:for-each-group按self::table分组,将table单独划分为一组,其余文本和内联元素(如b、i)归为连续组。
  2. 属性传递:仅给第一个生成的

    标签保留原

    的所有属性,符合示例输出要求。

  3. 身份模板复用:保留默认的身份模板,确保其他节点(如kk、table内部结构)原样复制,无需额外编写模板。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 01:22:03