如何在 XSLT 中获取特定 .ODS 单元格的任何类型的内容
How to get any type of content of specific .ODS cells in XSLT
我正在尝试使用 XSLT 转换 .ods
文件(来自 zip 的 content.xml
文件)以生成所需的 .xml
文件。
XSLT 使用元素的 "fixed" 位置来获取内容,但是在我的 .ods
文件中我有很多空白字段,我不知道如何让它们在 XSLT 中计数。
此外,我用 content.xml
做了一些实验,看看这些空白(空)单元格是否被保存。
在 content.xml
中我发现了类似的东西:
<table:table-column table:style-name="co1" table:number-columns-repeated="16384" table:default-cell-style-name="ce1"/>
<table:table-row table:number-rows-repeated="1048576" table:style-name="ro1">
这些值是否以某种方式(例如通过数学计算)表示空单元格或值在 .ods
文件中的实际位置?
我在这里分享我的文档,让你有更清晰的思路
.ods
例子:
这是我的 XSLT 文件:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
xmlns:espd="urn:com:grow:espd:02.00.00" xmlns:cac="urn:X-test:UBL:Pre-
award:CommonAggregate" xmlns:cbc="urn:X-test:UBL:Pre-award:CommonBasic"
<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="office:spreadsheet/table:table">
<xsl:variable name="test" select="table:table-row/table:table-cell"/>
<p><xsl:value-of select="$test/text:p[1]"/></p>
</xsl:template>
输出为:
burak burak5 burak6 burak2 burak3 burak4 burak7 burak9 burak8 burak10
问题:
如何通过对 content.xml
应用转换从单元格中获取单个值?
(例如:如何到达 D4
单元格?)
How to get the single values from the cells by applying a transformation on content.xml
?
.ods
文件 content.xml
中的 XML 数据以这种方式编码(始终以 table:
名称空间为前缀):
- 每个
table-cell
都包含在 table-row
中
- 空
table-cell
编码为空 RLE (Run-Length-Encoding),由 number-columns-repeated="..."
属性指示,必须跳过但计算在内
- 空
table-row
也使用 RLE 编码,由 number-rows-repeated="..."
属性指示
table-columns
好像只在开头用过
因此,要获取特定的单元格,例如D4
=4:4
,包括跳过的table-row
都要算上:
D4 = 4:4 = Get the fourth `table-row`, add one cell D1, then add number-columns-repeated="2"
这是一些 XSLT-1.0 代码(也可用于 2.0 和 3.0)以及 GetCellValue
示例:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
xmlns:espd="urn:com:grow:espd:02.00.00"
xmlns:cac="urn:X-test:UBL:Pre-award:CommonAggregate"
xmlns:cbc="urn:X-test:UBL:Pre-award:CommonBasic" exclude-result-prefixes="xs fn office style table text espd cac cbc">
<xsl:output method="html" version="4.0" encoding="UTF-8" indent="yes"/>
<xsl:variable name="str" select="'x:1 y:4'" /> <!-- define some coord system -->
<xsl:template match="/office:document-content/office:body/office:spreadsheet/table:table">
Table dimensions: <xsl:call-template name="GetDimensions" />
Value at 5x8: <xsl:call-template name="GetCellValue">
<xsl:with-param name="x" select="5" />
<xsl:with-param name="y" select="8" />
</xsl:call-template>
Value at 1x4: <xsl:call-template name="GetCellValue"> <!-- use string defined above -->
<xsl:with-param name="x" select="substring-after(substring-before($str,' '),'x:')" />
<xsl:with-param name="y" select="substring-after($str,'y:')" />
</xsl:call-template>
</xsl:template>
<xsl:template name="GetCellValue">
<xsl:param name="x" />
<xsl:param name="y" />
<xsl:variable name="targetRow" select="table:table-row[sum(preceding-sibling::*/@table:number-rows-repeated) + position() - count(preceding-sibling::*/@table:number-rows-repeated)= $y]" />
<xsl:variable name="targetCell" select="$targetRow/table:table-cell[sum(preceding-sibling::*/@table:number-columns-repeated) + position() - count(preceding-sibling::*/@table:number-columns-repeated) <= $x]" />
<xsl:copy-of select="$targetCell[last()]/text:p/text()" />
</xsl:template>
<xsl:template name="GetDimensions">
<xsl:variable name="firstRow" select="table:table-row[1]/table:table-cell" />
<xsl:variable name="firstColumn" select="table:table-row" />
<xsl:variable name="width" select="count($firstRow)+ sum($firstRow/@table:number-columns-repeated) - count($firstRow/@table:number-columns-repeated)" />
<xsl:variable name="height" select="count($firstColumn)+ sum($firstColumn/@table:number-rows-repeated) - count($firstColumn/@table:number-rows-repeated)" />
<xsl:value-of select="concat($width,'x',$height)" />
</xsl:template>
</xsl:stylesheet>
输出为:
Table dimensions: 5x12
Value at 5x8: burak9
Value at 1x4: burak4
编辑:
我修改了一个 xsl:call-template
以与自定义格式的字符串输入一起使用,例如x:1 y:4
.
编辑2:
XSLT-2.0 版本可以一次检索多个单元格作为 XML 个元素可以找到 .
我正在尝试使用 XSLT 转换 .ods
文件(来自 zip 的 content.xml
文件)以生成所需的 .xml
文件。
XSLT 使用元素的 "fixed" 位置来获取内容,但是在我的 .ods
文件中我有很多空白字段,我不知道如何让它们在 XSLT 中计数。
此外,我用 content.xml
做了一些实验,看看这些空白(空)单元格是否被保存。
在 content.xml
中我发现了类似的东西:
<table:table-column table:style-name="co1" table:number-columns-repeated="16384" table:default-cell-style-name="ce1"/>
<table:table-row table:number-rows-repeated="1048576" table:style-name="ro1">
这些值是否以某种方式(例如通过数学计算)表示空单元格或值在 .ods
文件中的实际位置?
我在这里分享我的文档,让你有更清晰的思路
.ods
例子:
这是我的 XSLT 文件:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
xmlns:espd="urn:com:grow:espd:02.00.00" xmlns:cac="urn:X-test:UBL:Pre-
award:CommonAggregate" xmlns:cbc="urn:X-test:UBL:Pre-award:CommonBasic"
<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="office:spreadsheet/table:table">
<xsl:variable name="test" select="table:table-row/table:table-cell"/>
<p><xsl:value-of select="$test/text:p[1]"/></p>
</xsl:template>
输出为:
burak burak5 burak6 burak2 burak3 burak4 burak7 burak9 burak8 burak10
问题:
如何通过对 content.xml
应用转换从单元格中获取单个值?
(例如:如何到达 D4
单元格?)
How to get the single values from the cells by applying a transformation on
content.xml
?
.ods
文件 content.xml
中的 XML 数据以这种方式编码(始终以 table:
名称空间为前缀):
- 每个
table-cell
都包含在table-row
中 - 空
table-cell
编码为空 RLE (Run-Length-Encoding),由number-columns-repeated="..."
属性指示,必须跳过但计算在内 - 空
table-row
也使用 RLE 编码,由number-rows-repeated="..."
属性指示 table-columns
好像只在开头用过
因此,要获取特定的单元格,例如D4
=4:4
,包括跳过的table-row
都要算上:
D4 = 4:4 = Get the fourth `table-row`, add one cell D1, then add number-columns-repeated="2"
这是一些 XSLT-1.0 代码(也可用于 2.0 和 3.0)以及 GetCellValue
示例:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
xmlns:espd="urn:com:grow:espd:02.00.00"
xmlns:cac="urn:X-test:UBL:Pre-award:CommonAggregate"
xmlns:cbc="urn:X-test:UBL:Pre-award:CommonBasic" exclude-result-prefixes="xs fn office style table text espd cac cbc">
<xsl:output method="html" version="4.0" encoding="UTF-8" indent="yes"/>
<xsl:variable name="str" select="'x:1 y:4'" /> <!-- define some coord system -->
<xsl:template match="/office:document-content/office:body/office:spreadsheet/table:table">
Table dimensions: <xsl:call-template name="GetDimensions" />
Value at 5x8: <xsl:call-template name="GetCellValue">
<xsl:with-param name="x" select="5" />
<xsl:with-param name="y" select="8" />
</xsl:call-template>
Value at 1x4: <xsl:call-template name="GetCellValue"> <!-- use string defined above -->
<xsl:with-param name="x" select="substring-after(substring-before($str,' '),'x:')" />
<xsl:with-param name="y" select="substring-after($str,'y:')" />
</xsl:call-template>
</xsl:template>
<xsl:template name="GetCellValue">
<xsl:param name="x" />
<xsl:param name="y" />
<xsl:variable name="targetRow" select="table:table-row[sum(preceding-sibling::*/@table:number-rows-repeated) + position() - count(preceding-sibling::*/@table:number-rows-repeated)= $y]" />
<xsl:variable name="targetCell" select="$targetRow/table:table-cell[sum(preceding-sibling::*/@table:number-columns-repeated) + position() - count(preceding-sibling::*/@table:number-columns-repeated) <= $x]" />
<xsl:copy-of select="$targetCell[last()]/text:p/text()" />
</xsl:template>
<xsl:template name="GetDimensions">
<xsl:variable name="firstRow" select="table:table-row[1]/table:table-cell" />
<xsl:variable name="firstColumn" select="table:table-row" />
<xsl:variable name="width" select="count($firstRow)+ sum($firstRow/@table:number-columns-repeated) - count($firstRow/@table:number-columns-repeated)" />
<xsl:variable name="height" select="count($firstColumn)+ sum($firstColumn/@table:number-rows-repeated) - count($firstColumn/@table:number-rows-repeated)" />
<xsl:value-of select="concat($width,'x',$height)" />
</xsl:template>
</xsl:stylesheet>
输出为:
Table dimensions: 5x12
Value at 5x8: burak9
Value at 1x4: burak4
编辑:
我修改了一个 xsl:call-template
以与自定义格式的字符串输入一起使用,例如x:1 y:4
.
编辑2:
XSLT-2.0 版本可以一次检索多个单元格作为 XML 个元素可以找到