如何通过列标题访问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() > 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>
关键要点
- 引入EXSLT命名空间:添加
xmlns:exsl="http://exslt.org/common",并在exclude-result-prefixes中排除该命名空间,避免输出冗余内容 - 转换临时变量为节点集:先将列标题与索引存入临时变量
$columnHeadings-temp,再通过exsl:node-set()转换为可通过XPath查询的节点集$columnHeadings - 修正语法错误:将原代码中错误的
<xsl value-of .../>改为标准的<xsl:value-of .../> - 通过列标题定位单元格:使用
table:table-cell[number($columnHeadings/heading[@name='First_Name'])]/text:p格式,即可根据列标题获取对应单元格的内容
内容的提问来源于stack exchange,提问作者dweipert
相关产品推荐
相关产品推荐

