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

如何通过列标题访问ODS表格中table-cell的值(XSLT 1.0)

解决LibreOffice ODS文件中通过列标题访问单元格的XSLT问题

问题背景

我有一个ODS表格,结构示例如下:

First_Name | Last_Name
Peter      | Parker
Emma       | Stone
...

需要通过列标题(第一行的列名)访问对应行的单元格值,而非依赖列索引——因为表格有184列,列名比索引更稳定,可移植性更强。

编写XSLT导出过滤器SuperBasicExportFilter.xslt时,尝试将列标题与对应索引存入变量$columnHeadings,但无法通过XPath表达式访问该变量内的元素,报错“Xpath evaluation returned no result”。试过包裹根元素、node-set函数、document()函数、xsl:key等方法均未解决。

环境信息

  • LibreOffice 7.4.5.1,内置libxslt 1.0处理器
  • 开启XSLT 2.0选项后无法生成输出,只能使用XSLT 1.0

解决方案

核心是引入EXSLT命名空间,使用exsl:node-set()将临时变量转换为可查询的节点集,同时修正属性赋值的语法错误,即可通过列标题定位对应单元格。

工作版XSLT代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
  xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
  xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
  xmlns:exsl="http://exslt.org/common"
  exclude-result-prefixes="table text office exsl"
>

  <xsl:output
    method="xml"
    indent="yes"
    encoding="UTF-8"
    omit-xml-declaration="no"
  />

  <xsl:template match="/">

    <xsl:variable name="columnHeadings-temp" xmlns="">
      <xsl:for-each select="//table:table/table:table-row[not(preceding::table:table-row)]//table:table-cell">
        <xsl:element name="heading">
          <xsl:attribute name="name">
            <xsl:value-of select="normalize-space(text:p)" />
          </xsl:attribute>
          <xsl:value-of select="position()" />
        </xsl:element>
      </xsl:for-each>
    </xsl:variable>
    <xsl:variable name="columnHeadings" select="exsl:node-set($columnHeadings-temp)" />

    <html>
      <body>
      <table>
        <xsl:for-each select="//table:table/table:table-row">

          <xsl:if test="position() &gt; 1">

            <tr>
              <td>
                First Column Value
                <xsl:value-of select="table:table-cell[number($columnHeadings/heading[@name='First_Name'])]/text:p" />
              </td>
              <td>
                Second Column Value
                <xsl:value-of select="table:table-cell[number($columnHeadings/heading[@name='Last_Name'])]/text:p" />
              </td>
            </tr>

          </xsl:if>

        </xsl:for-each>
      </table>
      </body>
    </html>

  </xsl:template>

</xsl:stylesheet>

关键要点

  1. 引入EXSLT命名空间:添加xmlns:exsl="http://exslt.org/common",并在exclude-result-prefixes中排除该命名空间,避免输出冗余内容
  2. 转换临时变量为节点集:先将列标题与索引存入临时变量$columnHeadings-temp,再通过exsl:node-set()转换为可通过XPath查询的节点集$columnHeadings
  3. 修正语法错误:将原代码中错误的<xsl value-of .../>改为标准的<xsl:value-of .../>
  4. 通过列标题定位单元格:使用table:table-cell[number($columnHeadings/heading[@name='First_Name'])]/text:p格式,即可根据列标题获取对应单元格的内容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 10:05:29