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

求助:使用XSLT将XML表格转换为结构化纯文本无法生成预期格式

解决XML表格转结构化纯文本的XSLT问题

嘿,我来帮你搞定这个XSLT转换的问题!你现在的代码只是把每一行的所有entry用冒号拼接后换行,但你需要的是表头和对应行的条目一一配对的格式,所以得调整一下思路,先把表头存起来,再和tbody里的每一行对应起来。

你的输入XML

<table>
  <tgroup> 
    <thead> 
      <row>
        <entry colname="col1">head1</entry>
        <entry colname="col2">head2</entry>
        <entry colname="col3">head3</entry>
      </row> 
    </thead> 
    <tbody> 
      <row>
        <entry>entry1</entry>
        <entry>entry2</entry>
        <entry>entry3</entry> 
      </row> 
      <row>
        <entry>entry4</entry>
        <entry>entry5</entry>
        <entry>entry6</entry> 
      </row> 
      <row>
        <entry>entry7</entry>
        <entry>entry8</entry>
        <entry>entry9</entry> 
      </row> 
    </tbody>
  </tgroup>
</table>

现有XSLT(问题所在)

你的当前代码会把thead的表头行也当成普通行处理,而且没有关联表头和条目,所以输出不符合预期:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" > 
  <xsl:output method="text" omit-xml-declaration="yes" indent="yes"/> 
  <xsl:template match="/"> 
    <xsl:for-each select="//row"> 
      <xsl:for-each select="entry"> 
        <xsl:value-of select="concat(.,':')"/> 
      </xsl:for-each> 
      <xsl:value-of select="concat('&#xA;','')"/> 
    </xsl:for-each> 
  </xsl:template> 
</xsl:stylesheet>

期望输出

head1:entry1 head2:entry2 head3:entry3
head1:entry4 head2:entry5 head3:entry6
head1:entry7 head2:entry8 head3:entry9

修改后的XSLT方案

下面是调整后的代码,完美匹配你的需求:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" omit-xml-declaration="yes" indent="yes"/>
  
  <!-- 先把表头的所有entry存为变量,方便后续引用 -->
  <xsl:variable name="headers" select="/table/tgroup/thead/row/entry"/>
  
  <xsl:template match="/">
    <!-- 只遍历tbody里的行,跳过表头行 -->
    <xsl:for-each select="/table/tgroup/tbody/row">
      <xsl:variable name="currentRow" select="."/>
      <!-- 遍历每个表头,找到对应位置的entry -->
      <xsl:for-each select="$headers">
        <xsl:variable name="pos" select="position()"/>
        <!-- 拼接表头和对应条目,最后一个条目后不加空格 -->
        <xsl:value-of select="concat(.,':',$currentRow/entry[$pos])"/>
        <xsl:if test="$pos != last()">
          <xsl:text> </xsl:text>
        </xsl:if>
      </xsl:for-each>
      <!-- 每行结束后换行 -->
      <xsl:text>&#xA;</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

代码说明

  1. 存储表头:用<xsl:variable>把表头的所有entry节点保存起来,后续通过位置索引匹配对应行的条目
  2. 遍历目标行:只选择tbody里的行,避免把表头行也输出成内容行
  3. 配对表头和条目:对每个表头,用position()获取它的位置,然后找到当前行对应位置的entry,拼接成表头:条目的格式
  4. 格式调整:每个配对之间加空格,最后一个配对后不加多余空格,每行结束后换行

这样运行后就能得到你想要的结构化纯文本啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 11:19:05