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

如何合并与文本交错的相邻兄弟codeph元素?

问题需求

需要将父元素中相邻的codeph直接兄弟元素(含子元素)合并为单个codeph元素,同时保留与文本节点的交错结构。

XML输入

<p>Information about specific mio levels, accessed as 
<codeph><i>metaMio</i></codeph><codeph>[</codeph><codeph><i>N</i></codeph><codeph>]</codeph>
, in which
<codeph><i>N</i></codeph><codeph> &lt; kMaxMioLevels</codeph>
.
</p>

期望XML输出

<p>Information about specific mio levels, accessed as 
<codeph><i>metaMio</i>[<i>N</i>]</codeph>
, in which
<codeph><i>N</i> &lt; kMaxMioLevels</codeph>
.
</p>

尝试的XSLT(存在重复问题)

<xsl:template match="codeph[not(preceding-sibling::node()[1][./local-name()='codeph'])][following-sibling::node()[1][./local-name()='codeph']]">
    <xsl:copy copy-namespaces="no">
        <xsl:apply-templates/>
        <xsl:choose>
            <xsl:when test="following-sibling::codeph[preceding-sibling::node()[position()=1][local-name()='codeph']]">
                <xsl:apply-templates select="following-sibling::codeph[preceding-sibling::node()[position()=1][local-name()='codeph']]" mode="codeph-merger"/>
            </xsl:when>
            <xsl:when test="following-sibling::*[1][text()[not(parent::codeph)]]"/>
        </xsl:choose>            
    </xsl:copy>
</xsl:template>

<xsl:template match="*" mode="codeph-merger">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="codeph[preceding-sibling::node()[1][local-name()='codeph']]"/>

当前输出(存在文本重复)

<p>Information about specific mio levels, accessed as
<codeph><i>metaMio</i>[<i>N</i>] &lt; kMaxMipLevels</codeph>
, in which 
<codeph><i>N</i> &lt; kMaxMipLevels</codeph>
.
</p>

解决方案(XSLT 2.0)

使用xsl:for-each-group的group-adjacent属性精准分组相邻codeph,避免内容重复:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- 身份模板:默认复制所有未匹配的节点 -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- 处理p元素的子节点,按是否为codeph分组 -->
    <xsl:template match="p">
        <xsl:copy>
            <xsl:for-each-group select="node()" group-adjacent="local-name()='codeph'">
                <!-- 合并相邻的codeph组为单个codeph元素 -->
                <xsl:if test="current-grouping-key()">
                    <codeph>
                        <xsl:apply-templates select="current-group()/node()"/>
                    </codeph>
                </xsl:if>
                <!-- 非codeph组直接输出原内容 -->
                <xsl:if test="not(current-grouping-key())">
                    <xsl:apply-templates select="current-group()"/>
                </xsl:if>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

方案说明

  1. 身份模板保证所有未匹配的节点(如嵌套的<i>元素、文本节点)原样复制,不破坏原有结构。
  2. 针对<p>的子节点,用group-adjacent="local-name()='codeph'"将连续的codeph归为一组,非codeph节点(文本、其他元素)单独成组。
  3. 对codeph组,创建新的<codeph>元素,将组内所有codeph的子节点(包括嵌套元素和文本)合并进去。
  4. 非codeph组直接输出,保留原有的文本和排版结构。

该方案能准确处理多组codeph与文本交错的场景,完全符合需求且无内容重复问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 15:15:05