我有一个非常大的电子表格,我正在尝试导出到XML。在转换期间跳过具有重复单元格的任何行。所以,如果有一行 1 2 2 2 3 4 5 只有前2个将被复制到XML文件中。我发现这是因为电子表格存储重复行的方式。我需要我的XSLT文件来处理连续的重复单元格,而不是跳过它们。
我正在使用LibreOffice Calc进行转换。
这是我的示例.xslt文件的一部分,它完成了繁重的工作:
<xsl:template match="office:spreadsheet/table:table">
<xsl:for-each select="table:table-row[position() > 0]">
<xsl:text>
</xsl:text>
<xsl:text>
</xsl:text>
<Column>
<xsl:text>
</xsl:text>
<p1><xsl:value-of select="table:table-cell[1]/text:p" /></p1>
<p1><xsl:value-of select="table:table-cell[2]/text:p" /></p1>
<p2><xsl:value-of select="table:table-cell[3]/text:p" /></p2>
<p3><xsl:value-of select="table:table-cell[4]/text:p" /></p3>
<p4><xsl:value-of select="table:table-cell[5]/text:p" /></p4>
<p5><xsl:value-of select="table:table-cell[6]/text:p" /></p5>
<p6><xsl:value-of select="table:table-cell[7]/text:p" /></p6>
<xsl:text>
</xsl:text>
</Column>
</xsl:for-each>
</xsl:template>
编辑:以下是我的示例电子表格在LibreOffice中的样子:
1 2 3 4 5
6 7 8 9 10
12 12 13 14 15
15 15 15 15 15
17 17 18 18 17
生成的XML文件:
<?xml version="1.0"?>
<root>
<Column>
<p1>1</p1><p1>2</p1><p2>3</p2><p3>4</p3><p4>5</p4><p5/><p6/>
</Column>
<Column>
<p1>6</p1><p1>7</p1><p2>8</p2><p3>9</p3><p4>10</p4><p5/><p6/>
</Column>
<Column>
<p1>12</p1><p1>13</p1><p2>14</p2><p3>15</p3><p4/><p5/><p6/>
</Column>
<Column>
<p1>15</p1><p1/><p2/><p3/><p4/><p5/><p6/>
</Column>
<Column>
<p1>17</p1><p1>18</p1><p2>17</p2><p3/><p4/><p5/><p6/>
</Column></root>
答案 0 :(得分:0)
在Open Document *.ods
文件中,相同的单元格不会存储冗余。相反,第一个单元格将有一个属性table:number-columns-repeated
,它会告诉重复计数:<table:table-cell table:number-columns-repeated="2" ...>
。
所以将XSLT
转换为需要所有元素的XML
必须重复生成元素。由于我们需要使用XSLT 1.0
,因此这并不像应该的那样简单。我们需要一个递归调用自己的模板。
您的编号元素名称p1
,p2
,...也不会让事情变得更容易。要实现这一点并根据结果输出元素而不是输入元素进行编号,我们必须首先在变量中收集输出元素,然后对该集合进行编号。
你的元素名称令人困惑。您呼叫Column
的是行,p
元素是单元格。所以我相应地重命名了它们。
所以有以下表格:
并使用导出XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" exclude-result-prefixes="office table text exsl">
<xsl:template match="/">
<xsl:element name="sheet">
<xsl:apply-templates select="/*/office:body" />
</xsl:element>
</xsl:template>
<xsl:template match="office:body">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="office:spreadsheet">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="office:spreadsheet/table:table">
<xsl:for-each select="table:table-row">
<xsl:element name="row">
<xsl:variable name="thecells">
<xsl:for-each select="table:table-cell">
<xsl:variable name="repeated">
<xsl:choose>
<xsl:when test="@table:number-columns-repeated">
<xsl:value-of select="@table:number-columns-repeated" />
</xsl:when>
<xsl:otherwise>
<xsl:text>1</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:call-template name="repeatecells">
<xsl:with-param name="start" select="1" />
<xsl:with-param name="end" select="$repeated"/>
</xsl:call-template>
</xsl:for-each>
</xsl:variable>
<xsl:for-each select="exsl:node-set($thecells)/cell">
<xsl:element name="{concat('cell', position())}"><xsl:value-of select="current()" /></xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:template>
<xsl:template name="repeatecells">
<xsl:param name="start"/>
<xsl:param name="end"/>
<xsl:if test="not($start > $end)">
<xsl:choose>
<xsl:when test="$start = $end">
<xsl:element name="cell"><xsl:value-of select="text:p" /></xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="mid" select= "floor(($start + $end) div 2)"/>
<xsl:call-template name="repeatecells">
<xsl:with-param name="start" select="$start"/>
<xsl:with-param name="end" select="$mid"/>
</xsl:call-template>
<xsl:call-template name="repeatecells">
<xsl:with-param name="start" select="$mid+1"/>
<xsl:with-param name="end" select="$end"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
结果:
<?xml version="1.0"?>
<sheet>
<row><cell1>P1</cell1><cell2>P2</cell2><cell3>P3</cell3><cell4>P4</cell4><cell5>P5</cell5><cell6>P6</cell6></row>
<row><cell1>1</cell1><cell2>1</cell2><cell3>1</cell3><cell4>1</cell4><cell5>2</cell5><cell6>2</cell6></row>
<row><cell1>1</cell1><cell2>2</cell2><cell3>2</cell3><cell4>2</cell4><cell5>2</cell5><cell6>3</cell6></row>
<row><cell1>1</cell1><cell2>1</cell2><cell3>1</cell3><cell4>2</cell4><cell5>2</cell5><cell6>2</cell6></row>
<row><cell1/><cell2>1</cell2><cell3>1</cell3><cell4/><cell5>2</cell5><cell6>2</cell6></row>
<row><cell1>1</cell1><cell2/><cell3/><cell4>2</cell4><cell5/><cell6/></row></sheet>