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

XSLT转换如何保留选中元素、属性及文本的正确顺序

问题核心原因

你现有代码无法按原有顺序输出内容,本质是犯了XSLT开发的常见错误:

  • 没有利用XSLT原生的节点遍历机制,在匹配<b>节点时手动硬编码用<xsl:value-of>分别选取<e>节点和当前节点文本值,完全打乱了XML文档里节点的原始排列顺序
  • 没有处理XML缩进产生的冗余空白节点,也没有对有效文本里的换行、连续空格做规范化
  • 标签和结构不符合预期:包裹属性值的标签写成了<sup>(预期是<sub>),缺少最外层的<output>根容器
  • 虽然写了<skip>节点的空匹配模板,但因为没有按顺序遍历所有子节点,这个过滤逻辑没有按预期生效
修正后的XSLT实现

直接替换你现有XSLT文件内容即可,不需要修改Java调用代码:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0">
  <xsl:output method="xml" indent="no" omit-xml-declaration="yes"/>
  <!-- 自动清除节点间纯缩进、换行产生的空白节点 -->
  <xsl:strip-space elements="*"/>

  <!-- 过滤冗余skip节点,不输出任何内容 -->
  <xsl:template match="skip"/>

  <!-- 匹配根节点<a>,生成外层<output>容器 -->
  <xsl:template match="/a">
    <output>
      <xsl:apply-templates select="b"/>
    </output>
  </xsl:template>

  <!-- 匹配<e>节点:生成<sub>标签包裹h属性值,再输出节点内的有效文本 -->
  <xsl:template match="e">
    <sub>
      <xsl:value-of select="@h"/>
    </sub>
    <xsl:text> </xsl:text>
    <xsl:value-of select="normalize-space(text())"/>
    <!-- 后续还有非空内容时补空格分隔,避免内容粘连 -->
    <xsl:if test="following-sibling::node()[not(self::skip)][normalize-space(.)]">
      <xsl:text> </xsl:text>
    </xsl:if>
  </xsl:template>

  <!-- 处理<b>节点下的直接有效文本,过滤空内容 -->
  <xsl:template match="b/text()[normalize-space(.)]">
    <xsl:value-of select="normalize-space(.)"/>
    <xsl:text> </xsl:text>
  </xsl:template>
</xsl:stylesheet>
关键实现说明
  • 保留原始顺序的核心是用<xsl:apply-templates>按文档顺序遍历节点,不要手动拼接不同位置的节点值,这是XSLT开发的基本原则
  • 不需要的属性(比如<b>的c属性、<e>的f属性)因为没有被主动选取,自然不会出现在输出里,不需要额外写过滤逻辑
  • normalize-space()函数会自动清除文本首尾的空白、把内部连续空白合并为单个空格,刚好适配你需要的文本格式
  • <xsl:strip-space elements="*">会提前删除纯格式用途的空白文本节点(就是XML缩进产生的换行、空格),减少后续的空白判断逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 19:12:28