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

XSLT 2.0节点拆分需求:按分隔符拆分para节点并保留子节点

XSLT 2.0 节点拆分解决方案:按分隔符拆分并保留原结构

输入XML

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:xlink="http://www.w3.org/1999/xlink">
 <para id="pa3" class="para_index">
  <alinea>Achard de Saint-Victor : <marquage typemarq="italique"><liensimple id="l3"    xlink:href="xxx://numero:isbn:xxxx/article:page:397">397</liensimple></marquage></alinea>
 </para>
</root>

期望输出XML

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:xlink="http://www.w3.org/1999/xlink">
 <para id="pa3">
     <listerelation type="1">
      <lrsource>
       <alinea>Achard de Saint-Victor</alinea>
      </lrsource>
      <lrcible>
       <alinea><marquage typemarq="italique"><liensimple id="l3" xlink:href="xxx://numero:isbn:xxxx/article:page:397">397</liensimple></marquage>
  </alinea>
      </lrcible>
     </listerelation>
    </para>
</root>

解决方案XSLT代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xlink="http://www.w3.org/1999/xlink">
    <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
    
    <!-- 全局默认复制规则:保留未特殊处理的节点与属性 -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <!-- 处理目标para节点,重构内部结构 -->
    <xsl:template match="para">
        <para id="{@id}">
            <listerelation type="1">
                <!-- 获取alinea下的所有子节点 -->
                <xsl:variable name="alinea-nodes" select="alinea/node()"/>
                <!-- 定位包含分隔符" : "的文本节点 -->
                <xsl:variable name="sep-node" select="$alinea-nodes[self::text()[contains(., ' : ')]]"/>
                <!-- 拆分文本节点为前后两段 -->
                <xsl:variable name="split-text" select="tokenize($sep-node, ' : ')"/>
                
                <lrsource>
                    <alinea>
                        <!-- 复制分隔符前的所有节点,加上拆分后的前半段文本 -->
                        <xsl:apply-templates select="$alinea-nodes[. << $sep-node]"/>
                        <xsl:value-of select="$split-text[1]"/>
                    </alinea>
                </lrsource>
                
                <lrcible>
                    <alinea>
                        <!-- 加上拆分后的后半段文本,复制分隔符后的所有节点 -->
                        <xsl:value-of select="$split-text[2]"/>
                        <xsl:apply-templates select="$alinea-nodes[. >> $sep-node]"/>
                    </alinea>
                </lrcible>
            </listerelation>
        </para>
    </xsl:template>
    
    <!-- 跳过原alinea节点的默认复制,避免重复生成 -->
    <xsl:template match="para/alinea"/>
</xsl:stylesheet>

关键逻辑说明

  • 默认复制模板:保证XML中未被单独处理的节点、属性和命名空间完整保留,避免信息丢失。
  • 节点拆分核心:
    1. 定位到包含目标分隔符:的文本节点,而非直接拆分整个字符串,以此保留原节点结构。
    2. 使用tokenize()拆分目标文本节点,再结合节点位置比较(<</>>),将分隔符前后的节点和文本分别归入对应标签。
  • 属性处理:重构<para>标签时仅保留id属性,移除原有的class属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 05:03:36