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

如何修改XSLT实现将XML文本行包装为<line>元素?

问题描述

XML输入(已添加root根节点适配XSLT处理)

<root>
Line 1
Line 2
Line 3</root>

期望输出

<root>
<line>Line 1</line>
<line>Line 2</line>
<line>Line 3</line></root>

当前使用的XSLT会将所有文本合并为单个<line>元素,需修改XSLT以实现预期输出。

当前XSLT代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="root">
<xsl:copy>
<xsl:apply-templates select="text()[normalize-space()]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<line>
  <xsl:value-of select="normalize-space()"/>
</line>
</xsl:template>
</xsl:stylesheet>
解决方案

原XSLT的问题在于,<root>下的所有内容是单个文本节点(包含换行和换行分隔的内容),匹配text()时会把整个文本节点作为一个整体处理,因此只会生成一个<line>元素。要按行拆分生成独立元素,需将文本节点按换行分割后逐个处理。

XSLT 1.0 实现(递归拆分)

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

  <!-- 保留root节点结构,调用拆分模板处理文本 -->
  <xsl:template match="root">
    <xsl:copy>
      <xsl:call-template name="split-lines">
        <xsl:with-param name="text" select="normalize-space(.)"/>
      </xsl:call-template>
    </xsl:copy>
  </xsl:template>

  <!-- 递归拆分文本为行 -->
  <xsl:template name="split-lines">
    <xsl:param name="text"/>
    <xsl:param name="delimiter" select="' '"/> <!-- normalize-space将换行转为空格 -->
    
    <xsl:if test="$text != ''">
      <!-- 提取第一行内容 -->
      <xsl:variable name="line" select="substring-before(concat($text, $delimiter), $delimiter)"/>
      <!-- 生成line元素 -->
      <line>
        <xsl:value-of select="$line"/>
      </line>
      <!-- 递归处理剩余文本 -->
      <xsl:call-template name="split-lines">
        <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

XSLT 2.0+ 实现(用tokenize函数)

如果环境支持XSLT 2.0及以上版本,可直接使用原生字符串分割函数简化代码:

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

  <xsl:template match="root">
    <xsl:copy>
      <xsl:for-each select="tokenize(normalize-space(.), ' ')">
        <line>
          <xsl:value-of select="."/>
        </line>
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

原理说明

  1. normalize-space(.)会将原文本中的换行、连续空白转为单个空格,同时去除首尾空白,统一文本分隔符。
  2. XSLT 1.0通过递归模板逐段提取分隔符前的内容,生成<line>元素;XSLT 2.0+则用tokenize直接拆分文本为序列,循环生成元素。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 12:35:28