优化项目结构、优化 maven 结构

This commit is contained in:
chenkailing
2021-02-10 00:58:13 +08:00
parent 28d3e05ca9
commit 2542a24675
3610 changed files with 77 additions and 180 deletions

View File

@@ -0,0 +1,636 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--***********************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
***********************************************************-->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dom="http://www.w3.org/2001/xml-events"
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
xmlns:math="http://www.w3.org/1998/Math/MathML"
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:ooo="http://openoffice.org/2004/office"
xmlns:oooc="http://openoffice.org/2004/calc"
xmlns:ooow="http://openoffice.org/2004/writer"
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible: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:xlink="http://www.w3.org/1999/xlink"
xmlns:xt="http://www.jclark.com/xt"
xmlns:common="http://exslt.org/common"
xmlns:xalan="http://xml.apache.org/xalan"
xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:c="urn:schemas-microsoft-com:office:component:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:x2="http://schemas.microsoft.com/office/excel/2003/xml" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exclude-result-prefixes="chart config dc dom dr3d draw fo form math meta number office ooo oooc ooow script style svg table text xlink xt common xalan">
<!-- Mapping @table:formula to @ss:Formula translating the expression syntax -->
<xsl:template match="@table:formula">
<xsl:param name="calculatedCellPosition" />
<xsl:param name="calculatedRowPosition" />
<xsl:attribute name="ss:Formula">
<xsl:call-template name="translate-formular-expression">
<xsl:with-param name="rowPos" select="$calculatedRowPosition" />
<xsl:with-param name="columnPos" select="$calculatedCellPosition" />
<xsl:with-param name="expression" select="." />
</xsl:call-template>
</xsl:attribute>
</xsl:template>
<!-- Translate OOOC formula expressions of table cells to spreadsheetml expression
For example:
"oooc:=ROUNDDOWN(123.321;2)"
to "=ROUNDDOWN(123.321,2)"
"oooc:=([.B2]-[.C2])"
to "=(RC[-2]-RC[-1])"
"oooc:=DCOUNTA([.E14:.F21];[.F14];[.H14:.I15])"
to "=DCOUNTA(R[-17]C[3]:R[-10]C[4],R[-17]C[4],R[-17]C[6]:R[-16]C[7])" -->
<xsl:template name="translate-formular-expression">
<!-- return position or range for formula or other -->
<xsl:param name="rowPos" /> <!-- the position in row (vertical) of cell -->
<xsl:param name="columnPos" /> <!-- the position in column (horizontal of cell) -->
<xsl:param name="expression" /> <!-- the expression string to be converted -->
<xsl:choose>
<xsl:when test="$expression != ''">
<xsl:choose>
<!-- OASIS Open Document XML formular expressions -->
<xsl:when test="starts-with($expression,'oooc:')">
<!-- giving out the '=', which will be removed with 'oooc:=' to enable recursive string parsing -->
<xsl:text>=</xsl:text>
<xsl:call-template name="function-parameter-mapping">
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="columnPos" select="$columnPos" />
<!-- 1) remove 'oooc:=' prefix and exchange ';' with ',' -->
<xsl:with-param name="expression" select="translate(substring($expression,7),';',',')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$expression" />
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$expression" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- As the function API of our Office and MS Office show differences in the argumentlists,
- sometimes the last parameter have to be neglected
- sometimes a default have to be added
these exchanges have to be done as well -->
<xsl:template name="function-parameter-mapping">
<xsl:param name="rowPos" /> <!-- the position in row (vertical of cell) -->
<xsl:param name="columnPos" /> <!-- the position in column (horizontal of cell) -->
<xsl:param name="expression" /> <!-- expression to be exchanged -->
<!-- Choose if the expression contains one of the function, which might need changes -->
<xsl:choose>
<!-- if not contain one of the functions, which need parameter mapping -->
<xsl:when test="not(contains($expression, 'ADDRESS(') or
contains($expression, 'CEILING(') or
contains($expression, 'FLOOR(') or
contains($expression, 'IF(') or
contains($expression, 'ROUND('))">
<!-- simply translate possily exisiting column & row references -->
<xsl:call-template name="translate-oooc-expression">
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="columnPos" select="$columnPos" />
<xsl:with-param name="expression" select="$expression"/>
</xsl:call-template>
</xsl:when>
<!-- functions to be mapped -->
<xsl:otherwise>
<xsl:variable name="functionPrefix" select="substring-before($expression, '(')" />
<xsl:variable name="expressionSuffix" select="substring-after($expression, '(')" />
<!-- translate in case the expression contains row/cell references aside of the function name -->
<xsl:call-template name="translate-oooc-expression">
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="columnPos" select="$columnPos" />
<xsl:with-param name="expression" select="$functionPrefix"/>
</xsl:call-template>
<!-- Prefix do not include the bracket -->
<xsl:text>(</xsl:text>
<xsl:choose>
<xsl:when test="not(contains($functionPrefix, 'ADDRESS') or
contains($functionPrefix, 'CEILING') or
contains($functionPrefix, 'FLOOR') or
(contains($functionPrefix, 'IF') and not(
contains($functionPrefix, 'COUNTIF') or
contains($functionPrefix, 'SUMIF'))) or
contains($functionPrefix, 'ROUND'))">
<xsl:call-template name="function-parameter-mapping">
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="columnPos" select="$columnPos" />
<xsl:with-param name="expression" select="$expressionSuffix"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="contains($functionPrefix, 'ADDRESS')">
<xsl:call-template name="find-parameters">
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="columnPos" select="$columnPos" />
<xsl:with-param name="expressionSuffix" select="$expressionSuffix"/>
<xsl:with-param name="parameterRemoval" select="4" />
</xsl:call-template>
</xsl:when>
<xsl:when test="contains($functionPrefix, 'CEILING') or
contains($functionPrefix, 'FLOOR')">
<xsl:call-template name="find-parameters">
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="columnPos" select="$columnPos" />
<xsl:with-param name="expressionSuffix" select="$expressionSuffix"/>
<xsl:with-param name="parameterRemoval" select="3" />
</xsl:call-template>
</xsl:when>
<xsl:when test="contains($functionPrefix, 'IF')">
<xsl:if test="not(contains($functionPrefix, 'COUNTIF') or
contains($functionPrefix, 'SUMIF'))">
<xsl:call-template name="find-parameters">
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="columnPos" select="$columnPos" />
<xsl:with-param name="expressionSuffix" select="$expressionSuffix"/>
<xsl:with-param name="parameterAddition" select="'true'" />
<xsl:with-param name="additonAfterLastParameter" select="2" />
</xsl:call-template>
</xsl:if>
</xsl:when>
<xsl:when test="contains($functionPrefix, 'ROUND')">
<xsl:call-template name="find-parameters">
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="columnPos" select="$columnPos" />
<xsl:with-param name="expressionSuffix" select="$expressionSuffix"/>
<xsl:with-param name="parameterAddition" select="'null'" />
<xsl:with-param name="additonAfterLastParameter" select="1" />
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Each parameter of the argumentlist have to be determined.
Due to the low level string functionlity in XSLT it becomes a clumsy task -->
<xsl:template name="find-parameters">
<!-- used for mapping of row/column reference -->
<xsl:param name="rowPos" /> <!-- the position in row (vertical of cell) -->
<xsl:param name="columnPos" /> <!-- the position in column (horizontal of cell) -->
<!-- used for mapping of parameter -->
<xsl:param name="parameterRemoval" />
<xsl:param name="parameterAddition" />
<xsl:param name="additonAfterLastParameter" />
<!-- used as helper to find a parameter -->
<xsl:param name="expressionSuffix" />
<xsl:param name="parameterNumber" select="1" />
<xsl:variable name="parameter">
<xsl:call-template name="getParameter">
<xsl:with-param name="expressionSuffix" select="$expressionSuffix"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<!-- if it is not the last parameter -->
<xsl:when test="starts-with(substring-after($expressionSuffix, $parameter), ',')">
<!-- searches the argument for functions to be mapped -->
<xsl:if test="not($parameterRemoval = $parameterNumber)">
<xsl:call-template name="function-parameter-mapping">
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="columnPos" select="$columnPos" />
<xsl:with-param name="expression">
<xsl:choose>
<!-- in case a character will be removed the preceding won't make a comma -->
<xsl:when test="$parameterRemoval = ($parameterNumber + 1)">
<xsl:value-of select="$parameter" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($parameter, ',')" />
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
</xsl:call-template>
</xsl:if>
<!-- searches for the next parameter -->
<xsl:call-template name="find-parameters">
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="columnPos" select="$columnPos" />
<xsl:with-param name="expressionSuffix" select="substring-after(substring-after($expressionSuffix, $parameter),',')"/>
<xsl:with-param name="parameterAddition" select="$parameterAddition" />
<xsl:with-param name="parameterRemoval" select="$parameterRemoval" />
<xsl:with-param name="additonAfterLastParameter" select="$additonAfterLastParameter" />
<xsl:with-param name="parameterNumber" select="$parameterNumber + 1" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- the last parameter -->
<xsl:choose>
<xsl:when test="$parameterRemoval = $parameterNumber">
<!-- searches the rest of the expression for functions to be mapped -->
<xsl:call-template name="function-parameter-mapping">
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="columnPos" select="$columnPos" />
<xsl:with-param name="expression" select="substring-after($expressionSuffix, $parameter)"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$parameterAddition and ($parameterNumber = $additonAfterLastParameter)">
<!-- searches the rest of the expression for functions to be mapped -->
<xsl:call-template name="function-parameter-mapping">
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="columnPos" select="$columnPos" />
<xsl:with-param name="expression" select="$parameter" />
</xsl:call-template>
<!-- searches last parameter and additional parameters for functions to be mapped -->
<xsl:call-template name="function-parameter-mapping">
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="columnPos" select="$columnPos" />
<!-- for the final parameter the latter substring is the ')' -->
<xsl:with-param name="expression" select="concat(',', $parameterAddition, substring-after($expressionSuffix, $parameter))"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- searches the argument for functions to be mapped -->
<xsl:call-template name="function-parameter-mapping">
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="columnPos" select="$columnPos" />
<xsl:with-param name="expression" select="$parameter" />
</xsl:call-template>
<!-- searches the rest of the expression for functions to be mapped -->
<xsl:call-template name="function-parameter-mapping">
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="columnPos" select="$columnPos" />
<xsl:with-param name="expression" select="substring-after($expressionSuffix, $parameter)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="getParameter">
<xsl:param name="closingBracketCount" select="0" />
<xsl:param name="openingBracketCount" select="0" />
<xsl:param name="expressionSuffix" />
<xsl:param name="parameterCandidate">
<xsl:choose>
<!-- if there are multiple parameter -->
<xsl:when test="contains(substring-before($expressionSuffix, ')'), ',')">
<xsl:value-of select="substring-before($expressionSuffix, ',')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring-before($expressionSuffix, ')')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:param>
<xsl:param name="earlierCandidate" select="$parameterCandidate" />
<xsl:choose>
<xsl:when test="contains($parameterCandidate, '(') or contains($parameterCandidate, ')')">
<xsl:choose>
<!-- contains only closing bracket(s) -->
<xsl:when test="contains($parameterCandidate, '(') and not(contains($parameterCandidate, ')'))">
<xsl:call-template name="getParameter">
<xsl:with-param name="openingBracketCount" select="$openingBracketCount + 1" />
<xsl:with-param name="closingBracketCount" select="$closingBracketCount" />
<xsl:with-param name="parameterCandidate" select="substring-after($parameterCandidate, '(')" />
<xsl:with-param name="earlierCandidate" select="$earlierCandidate" />
<xsl:with-param name="expressionSuffix" select="$expressionSuffix"/>
</xsl:call-template>
</xsl:when>
<!-- contains only opening bracket(s) -->
<xsl:when test="not(contains($parameterCandidate, '(')) and contains($parameterCandidate, ')')">
<xsl:call-template name="getParameter">
<xsl:with-param name="openingBracketCount" select="$openingBracketCount" />
<xsl:with-param name="closingBracketCount" select="$closingBracketCount + 1" />
<xsl:with-param name="parameterCandidate" select="substring-after($parameterCandidate, ')')" />
<xsl:with-param name="earlierCandidate" select="$earlierCandidate" />
<xsl:with-param name="expressionSuffix" select="$expressionSuffix"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="string-length(substring-before($parameterCandidate, '(')) &lt;
string-length(substring-before($parameterCandidate, ')'))">
<xsl:call-template name="getParameter">
<xsl:with-param name="openingBracketCount" select="$openingBracketCount + 1" />
<xsl:with-param name="closingBracketCount" select="$closingBracketCount" />
<xsl:with-param name="parameterCandidate" select="substring-after($parameterCandidate, '(')" />
<xsl:with-param name="earlierCandidate" select="$earlierCandidate" />
<xsl:with-param name="expressionSuffix" select="$expressionSuffix"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="getParameter">
<xsl:with-param name="openingBracketCount" select="$openingBracketCount" />
<xsl:with-param name="closingBracketCount" select="$closingBracketCount + 1" />
<xsl:with-param name="parameterCandidate" select="substring-after($parameterCandidate, ')')" />
<xsl:with-param name="earlierCandidate" select="$earlierCandidate" />
<xsl:with-param name="expressionSuffix" select="$expressionSuffix"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$openingBracketCount = $closingBracketCount">
<xsl:value-of select="$earlierCandidate" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$earlierCandidate" />
<xsl:variable name="parameterCandidate2">
<xsl:variable name="formularAfterCandidate" select="substring-after($expressionSuffix, $earlierCandidate)" />
<xsl:variable name="parameterTillBracket" select="concat(substring-before($formularAfterCandidate,')'),')')" />
<xsl:variable name="parameterTillComma" select="substring-before(substring-after($expressionSuffix, $parameterTillBracket),',')" />
<xsl:choose>
<xsl:when test="string-length($parameterTillComma) &gt; 0 and
not(contains($parameterTillComma, '('))">
<xsl:choose>
<xsl:when test="starts-with($formularAfterCandidate, ',')">
<xsl:value-of select="concat(',',substring-before(substring-after($formularAfterCandidate,','),','))"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring-before($formularAfterCandidate,',')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$parameterTillBracket"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:call-template name="getParameter">
<xsl:with-param name="closingBracketCount" select="$closingBracketCount" />
<xsl:with-param name="openingBracketCount" select="$openingBracketCount" />
<xsl:with-param name="parameterCandidate" select="$parameterCandidate2" />
<xsl:with-param name="earlierCandidate" select="$parameterCandidate2" />
<xsl:with-param name="expressionSuffix" select="$expressionSuffix" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Mapping table-cell definitions by exchangomg all table cell definitions:
a) a pair of cells e.g. "[.E14:.F21]" to "R[-17]C[3]:R[-10]C[4]"
b) a single cell e.g. "[.F14]" to "R[-17]"-->
<xsl:template name="translate-oooc-expression">
<xsl:param name="rowPos" /> <!-- the position in row (vertical of cell) -->
<xsl:param name="columnPos" /> <!-- the position in column (horizontal of cell) -->
<xsl:param name="expression" /> <!-- expression to be exchanged -->
<xsl:choose>
<xsl:when test="contains($expression, '[')">
<!-- Giving out the part before '[.' -->
<xsl:value-of select="substring-before($expression, '[')" />
<!-- Mapping cell definitions
1) a pair of cells e.g. "[.E14:.F21]" to "R[-17]C[3]:R[-10]C[4]"
2) a single cell e.g. "[.F14]" to "R[-17]"-->
<xsl:variable name="remainingExpression" select="substring-after($expression, '[')"/>
<xsl:choose>
<xsl:when test="contains(substring-before($remainingExpression, ']'), ':')">
<xsl:call-template name="translate-cell-expression">
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="columnPos" select="$columnPos" />
<xsl:with-param name="expression" select="substring-before($remainingExpression, ':')" />
</xsl:call-template>
<xsl:value-of select="':'" />
<xsl:call-template name="translate-cell-expression">
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="columnPos" select="$columnPos" />
<xsl:with-param name="expression" select="substring-after(substring-before($remainingExpression, ']'), ':')" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="translate-cell-expression">
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="columnPos" select="$columnPos" />
<xsl:with-param name="expression" select="substring-before($remainingExpression, ']')" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="translate-oooc-expression">
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="columnPos" select="$columnPos" />
<xsl:with-param name="expression" select="substring-after($remainingExpression,']')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- Giving out the remaining part -->
<xsl:value-of select="$expression" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- A cell expression has usually starts with a '.' otherwise it references to a sheet -->
<xsl:template name="translate-cell-expression">
<xsl:param name="rowPos" /> <!-- the vertical position of the current cell -->
<xsl:param name="columnPos" /> <!-- the horizontal position of the current cell -->
<xsl:param name="targetRowPos" select="0"/> <!-- the vertical position of the target cell -->
<xsl:param name="targetColumnPos" select="0"/> <!-- the horizontal position of the target cell -->
<xsl:param name="charPos" select="0"/> <!-- current column position (needed for multiplying) -->
<xsl:param name="digitPos" select="0"/> <!-- current row position (needed for multiplying) -->
<xsl:param name="expression" /> <!-- expression to be parsed by character -->
<xsl:param name="isRow" select="true()"/> <!-- the string (e.g. $D39 is parsed character per character from the back,
first the row, later the column is parsed -->
<xsl:choose>
<xsl:when test="starts-with($expression, '.')">
<xsl:variable name="expLength" select="string-length($expression)" />
<xsl:choose>
<!-- parsing from the end, till only the '.' remains -->
<xsl:when test="$expLength != 1">
<xsl:variable name="token" select="substring($expression, $expLength)" />
<xsl:choose>
<xsl:when test="$token='0' or $token='1' or $token='2' or $token='3' or $token='4' or $token='5' or $token='6' or $token='7' or $token='8' or $token='9'">
<xsl:variable name="multiplier">
<xsl:call-template name="calculate-square-numbers">
<xsl:with-param name="base" select="10" />
<xsl:with-param name="exponent" select="$digitPos"/>
</xsl:call-template>
</xsl:variable>
<xsl:call-template name="translate-cell-expression">
<xsl:with-param name="columnPos" select="$columnPos" />
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="targetColumnPos" select="$targetColumnPos" />
<xsl:with-param name="targetRowPos" select="$targetRowPos + $multiplier * $token" />
<xsl:with-param name="digitPos" select="$digitPos + 1" />
<xsl:with-param name="charPos" select="$charPos" />
<!-- removing the last character-->
<xsl:with-param name="expression" select="substring($expression, 1, $expLength - 1)" />
<xsl:with-param name="isRow" select="true()" />
</xsl:call-template>
</xsl:when>
<xsl:when test="$token = '$'">
<xsl:choose>
<!-- if this is the first '$' after '.' (column-->
<xsl:when test="$expLength = 2">
<xsl:text>C</xsl:text><xsl:value-of select="$targetColumnPos"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>R</xsl:text><xsl:value-of select="$targetRowPos"/>
<xsl:call-template name="translate-cell-expression">
<xsl:with-param name="columnPos" select="$columnPos" />
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="targetColumnPos" select="$targetColumnPos" />
<xsl:with-param name="targetRowPos" select="$targetRowPos" />
<xsl:with-param name="charPos" select="$charPos" />
<!-- removing the last character-->
<xsl:with-param name="expression" select="substring($expression, 1, $expLength - 1)" />
<xsl:with-param name="isRow" select="false()" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<!-- in case of a letter -->
<xsl:otherwise>
<xsl:if test="$isRow">
<xsl:text>R</xsl:text>
<xsl:if test="$targetRowPos != $rowPos">
<xsl:text>[</xsl:text><xsl:value-of select="$targetRowPos - $rowPos"/><xsl:text>]</xsl:text>
</xsl:if>
</xsl:if>
<xsl:variable name="multiplier">
<xsl:call-template name="calculate-square-numbers">
<xsl:with-param name="base" select="26" />
<xsl:with-param name="exponent" select="$charPos"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="tokenNumber">
<xsl:call-template name="character-to-number">
<xsl:with-param name="character" select="$token" />
</xsl:call-template>
</xsl:variable>
<xsl:call-template name="translate-cell-expression">
<xsl:with-param name="columnPos" select="$columnPos" />
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="targetColumnPos" select="$targetColumnPos + $multiplier * $tokenNumber" />
<xsl:with-param name="targetRowPos" select="$targetRowPos" />
<xsl:with-param name="digitPos" select="$digitPos" />
<xsl:with-param name="charPos" select="$charPos + 1" />
<!-- removing the last character-->
<xsl:with-param name="expression" select="substring($expression, 1, $expLength - 1)" />
<xsl:with-param name="isRow" select="false()" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:text>C</xsl:text>
<xsl:if test="$targetColumnPos != $columnPos">
<xsl:text>[</xsl:text><xsl:value-of select="$targetColumnPos - $columnPos"/><xsl:text>]</xsl:text>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="sheetName" select="substring-before($expression, '.')" />
<xsl:value-of select="$sheetName"/><xsl:text>!</xsl:text>
<xsl:call-template name="translate-cell-expression">
<xsl:with-param name="rowPos" select="$rowPos" />
<xsl:with-param name="columnPos" select="$columnPos" />
<xsl:with-param name="expression" select="substring-after($expression, $sheetName)" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="calculate-square-numbers">
<xsl:param name="base" />
<xsl:param name="exponent" />
<xsl:param name="return" select="1" />
<xsl:choose>
<xsl:when test="$exponent > '1'">
<xsl:call-template name="calculate-square-numbers">
<xsl:with-param name="base" select="$base" />
<xsl:with-param name="exponent" select="$exponent - 1"/>
<xsl:with-param name="return" select="$return * $base" />
</xsl:call-template>
</xsl:when>
<xsl:when test="$exponent = '1'">
<xsl:value-of select="$return * $base"/>
</xsl:when>
<!-- if exponent is equal '0' -->
<xsl:otherwise>
<xsl:value-of select="1"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="character-to-number">
<xsl:param name="character" />
<xsl:choose>
<xsl:when test="$character = 'A'">1</xsl:when>
<xsl:when test="$character = 'B'">2</xsl:when>
<xsl:when test="$character = 'C'">3</xsl:when>
<xsl:when test="$character = 'D'">4</xsl:when>
<xsl:when test="$character = 'E'">5</xsl:when>
<xsl:when test="$character = 'F'">6</xsl:when>
<xsl:when test="$character = 'G'">7</xsl:when>
<xsl:when test="$character = 'H'">8</xsl:when>
<xsl:when test="$character = 'I'">9</xsl:when>
<xsl:when test="$character = 'J'">10</xsl:when>
<xsl:when test="$character = 'K'">11</xsl:when>
<xsl:when test="$character = 'L'">12</xsl:when>
<xsl:when test="$character = 'M'">13</xsl:when>
<xsl:when test="$character = 'N'">14</xsl:when>
<xsl:when test="$character = 'O'">15</xsl:when>
<xsl:when test="$character = 'P'">16</xsl:when>
<xsl:when test="$character = 'Q'">17</xsl:when>
<xsl:when test="$character = 'R'">18</xsl:when>
<xsl:when test="$character = 'S'">19</xsl:when>
<xsl:when test="$character = 'T'">20</xsl:when>
<xsl:when test="$character = 'U'">21</xsl:when>
<xsl:when test="$character = 'V'">22</xsl:when>
<xsl:when test="$character = 'W'">23</xsl:when>
<xsl:when test="$character = 'X'">24</xsl:when>
<xsl:when test="$character = 'Y'">25</xsl:when>
<xsl:when test="$character = 'Z'">26</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

View File

@@ -0,0 +1,413 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--***********************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
***********************************************************-->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dom="http://www.w3.org/2001/xml-events"
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
xmlns:math="http://www.w3.org/1998/Math/MathML"
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:ooo="http://openoffice.org/2004/office"
xmlns:oooc="http://openoffice.org/2004/calc"
xmlns:ooow="http://openoffice.org/2004/writer"
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible: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:xlink="http://www.w3.org/1999/xlink"
xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:c="urn:schemas-microsoft-com:office:component:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:x2="http://schemas.microsoft.com/office/excel/2003/xml" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exclude-result-prefixes="chart config dc dom dr3d draw fo form math meta number office ooo oooc ooow script style svg table text xlink">
<!--+++++ INCLUDED XSL MODULES +++++-->
<!-- helper collection, to convert measures (e.g. inch to pixel using DPI (dots per inch) parameter)-->
<xsl:import href="../../common/measure_conversion.xsl" />
<!-- excel table handling -->
<xsl:include href="table.xsl" />
<!-- mapping rules of office style properties to Excel style properties -->
<xsl:include href="style_mapping.xsl" />
<!-- creating the Excel styles element -->
<xsl:include href="styles.xsl" />
<!-- mapping formalar Expressions -->
<xsl:include href="formular.xsl" />
<xsl:output method = "xml"
indent = "no"
encoding = "UTF-8"
omit-xml-declaration = "no" />
<xsl:strip-space elements="ss:Data html:Data" />
<!-- common table handling -->
<xsl:variable name="namespace" select="'urn:schemas-microsoft-com:office:spreadsheet'" />
<!--+++++ PARAMETER SECTION +++++-->
<!-- OPTIONAL: (MANDATORY: for all input document with relative external links): parameter is a (relative) URL to the target directory.
Relative links from the office document (e.g. to external graphics) will get this parameter as a prefix -->
<xsl:param name="targetBaseURL" select="'./'" />
<!-- OPTIONAL: (MANDATORY: for input document with relative internal links)
To access contents of a office file (content like the meta.xml, styles.xml file or graphics) a URL could be choosen.
This could be even a JAR URL. The sourceBase of the content URL "jar:file:/C:/temp/Test.sxw!/content.xml" would be
"jar:file:/C:/temp/Test.sxw!/" for example.
When working with OpenOffice API a Package-URL encoded over HTTP can be used to access the jared contents of the the jared document. -->
<xsl:param name="sourceBaseURL" select="'./'" />
<!-- OPTIONAL: (MANDATORY: for session management by URL rewriting)
Useful for WebApplications: if a HTTP session is not cookie based, URL rewriting is beeing used (the session is appended to the URL).
This URL session is used for example when links to graphics are created by XSLT. Otherwise the user havt to log again in for every graphic he liks to see. -->
<xsl:param name="optionalURLSuffix" />
<!-- OPTIONAL: URL to office meta file (flat xml use the URL to the input file) -->
<xsl:param name="metaFileURL" />
<!-- OPTIONAL: URL to office meta file (flat xml use the URL to the input file) -->
<xsl:param name="stylesFileURL" />
<!-- OPTIONAL: in case of using a different processor than a JAVA XSLT, you can unable the Java functionality
(e.g. encoding chapter names for the content-table as href and anchors ) -->
<xsl:param name="java" select="true()" />
<xsl:param name="javaEnabled" select="boolean($java)" />
<!-- OPTIONAL: for activating the debug mode set the variable here to 'true()' or give any value from outside -->
<xsl:param name="debug" select="false()" />
<xsl:param name="debugEnabled" select="boolean($debug)" />
<!-- matching configuration entries -->
<xsl:key name="config" use="@config:name"
match="/*/office:settings/config:config-item-set/config:config-item-map-indexed/config:config-item-map-entry/config:config-item |
/*/office:settings/config:config-item-set/config:config-item-map-indexed/config:config-item-map-entry/config:config-item-map-named/config:config-item-map-entry/config:config-item" />
<xsl:key name="colors" match="/*/office:styles//@*[name() = 'fo:background-color' or name() = 'fo:color'] |
/*/office:automatic-styles//@*[name() = 'fo:background-color' or name() = 'fo:color']" use="/" />
<xsl:key name="colorRGB" match="@fo:background-color | @fo:color" use="." />
<!-- *************************** -->
<!-- *** Built up Excel file *** -->
<!-- *************************** -->
<xsl:template match="/">
<xsl:processing-instruction name="mso-application">progid="Excel.Sheet"</xsl:processing-instruction>
<!-- Note: for debugging purpose include schema location
<Workbook xsi:schemaLocation="urn:schemas-microsoft-com:office:spreadsheet <YOUR_SCHEMA_URL>/excelss.xsd"> -->
<Workbook>
<!-- adding some default settings -->
<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
<Colors>
<xsl:for-each select="key('colors', /)
[generate-id(.) =
generate-id(key('colorRGB', .)[1]) and starts-with(., '#')] ">
<xsl:sort select="." />
<Color>
<Index><xsl:value-of select="position() + 2" /></Index>
<RGB><xsl:value-of select="." /></RGB>
</Color>
</xsl:for-each>
<xsl:for-each select="key('config', 'TabColor')[not(.=preceding::config:config-item)]">
<xsl:sort select="." />
<Color>
<Index><xsl:value-of select="56 - position()" /></Index>
<RGB>
<xsl:call-template name="colordecimal2rgb">
<xsl:with-param name="colordecimal" select="."/>
</xsl:call-template>
</RGB>
</Color>
</xsl:for-each>
</Colors>
</OfficeDocumentSettings>
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
<xsl:if test="key('config', 'HasSheetTabs') = 'false'">
<xsl:element name="HideWorkbookTabs" />
</xsl:if>
<WindowHeight>9000</WindowHeight>
<WindowWidth>13860</WindowWidth>
<WindowTopX>240</WindowTopX>
<WindowTopY>75</WindowTopY>
<ProtectStructure>False</ProtectStructure>
<ProtectWindows>False</ProtectWindows>
</ExcelWorkbook>
<!-- Note: the following handling will exchange the default, later
<x:ExcelWorkbook>
<xsl:apply-templates select="table:calculation-settings" />
</x:ExcelWorkbook>
-->
<xsl:element name="Styles">
<!-- our application default will not be used for export to Excel
<xsl:apply-templates select="/*/office:styles/style:default-style" mode="styles" />-->
<xsl:apply-templates select="/*/office:styles/style:style" mode="styles" />
<xsl:apply-templates select="/*/office:automatic-styles/style:style" mode="styles" >
<xsl:with-param name="isAutomatic" select="true()" />
</xsl:apply-templates>
</xsl:element>
<xsl:apply-templates select="/*/office:body" />
</Workbook>
</xsl:template>
<xsl:template name="colordecimal2rgb">
<xsl:param name="colordecimal"/>
<xsl:choose>
<xsl:when test="$colordecimal &lt;= 16777215 and $colordecimal &gt;= 65536">
<xsl:variable name="redValue" select="floor(($colordecimal) div 65536)"/>
<xsl:variable name="greenValue" select="floor(($colordecimal - ($redValue*65536)) div 256)"/>
<xsl:variable name="blueValue" select="$colordecimal - ($redValue*65536) - ($greenValue*256)"/>
<xsl:call-template name="dec_rgb2Hex">
<xsl:with-param name="decRedValue" select="$redValue"/>
<xsl:with-param name="decGreenValue" select="$greenValue"/>
<xsl:with-param name="decBlueValue" select="$blueValue"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$colordecimal &lt;= 65535 and $colordecimal &gt;= 256">
<xsl:variable name="redValue" select="0"/>
<xsl:variable name="greenValue" select="$colordecimal div 256"/>
<xsl:variable name="blueValue" select="$colordecimal - ($greenValue*256)"/>
<xsl:call-template name="dec_rgb2Hex">
<xsl:with-param name="decRedValue" select="$redValue"/>
<xsl:with-param name="decGreenValue" select="$greenValue"/>
<xsl:with-param name="decBlueValue" select="$blueValue"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="$colordecimal &lt;= 255 and $colordecimal &gt;= 0">
<xsl:variable name="redValue" select="0"/>
<xsl:variable name="greenValue" select="0"/>
<xsl:variable name="blueValue" select="$colordecimal"/>
<xsl:call-template name="dec_rgb2Hex">
<xsl:with-param name="decRedValue" select="$redValue"/>
<xsl:with-param name="decGreenValue" select="$greenValue"/>
<xsl:with-param name="decBlueValue" select="$blueValue"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
</xsl:template>
<xsl:template name="dec_rgb2Hex">
<xsl:param name="decRedValue"/>
<xsl:param name="decGreenValue"/>
<xsl:param name="decBlueValue"/>
<xsl:variable name="hexRedValue">
<xsl:variable name="tmpHexRedValue">
<xsl:call-template name="decimal2hex">
<xsl:with-param name="dec-number" select="$decRedValue"/>
<xsl:with-param name="last-value" select="'H'"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="string-length($tmpHexRedValue) = 1">
<xsl:value-of select="concat('0',$tmpHexRedValue)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$tmpHexRedValue"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="hexGreenValue">
<xsl:variable name="tmpHexGreenValue">
<xsl:call-template name="decimal2hex">
<xsl:with-param name="dec-number" select="$decGreenValue"/>
<xsl:with-param name="last-value" select="'H'"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="string-length($tmpHexGreenValue) = 1">
<xsl:value-of select="concat('0',$tmpHexGreenValue)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$tmpHexGreenValue"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="hexBlueValue">
<xsl:variable name="tmpHexBlueValue">
<xsl:call-template name="decimal2hex">
<xsl:with-param name="dec-number" select="$decBlueValue"/>
<xsl:with-param name="last-value" select="'H'"/>
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="string-length($tmpHexBlueValue) = 1">
<xsl:value-of select="concat('0',$tmpHexBlueValue)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$tmpHexBlueValue"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:value-of select="concat('#',$hexRedValue,$hexGreenValue,$hexBlueValue)"/>
</xsl:template>
<xsl:template name="decimal2hex">
<!-- transforms a decimal number to a hex number,only for two-bit hex(less than 256 in decimal) currently -->
<xsl:param name="dec-number"/>
<xsl:param name="last-value"/>
<xsl:variable name="current-value">
<xsl:call-template name="decNumber2hex">
<xsl:with-param name="dec-value">
<xsl:if test="$dec-number &gt; 15">
<xsl:value-of select="floor($dec-number div 16)"/>
</xsl:if>
<xsl:if test="$dec-number &lt; 16">
<xsl:value-of select="$dec-number"/>
</xsl:if>
</xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:if test="$dec-number &gt; 15">
<xsl:call-template name="decimal2hex">
<xsl:with-param name="dec-number" select="$dec-number mod 16"/>
<xsl:with-param name="last-value" select="concat($last-value,$current-value)"/>
</xsl:call-template>
</xsl:if>
<xsl:if test="$dec-number &lt; 16">
<xsl:value-of select="substring-after(concat($last-value,$current-value),'H')"/>
</xsl:if>
</xsl:template>
<xsl:template name="decNumber2hex">
<!-- return a hex number for a decimal character -->
<xsl:param name="dec-value"/>
<xsl:choose>
<xsl:when test="$dec-value = 10">
<xsl:value-of select="'A'"/>
</xsl:when>
<xsl:when test="$dec-value = 11">
<xsl:value-of select="'B'"/>
</xsl:when>
<xsl:when test="$dec-value = 12">
<xsl:value-of select="'C'"/>
</xsl:when>
<xsl:when test="$dec-value = 13">
<xsl:value-of select="'D'"/>
</xsl:when>
<xsl:when test="$dec-value = 14">
<xsl:value-of select="'E'"/>
</xsl:when>
<xsl:when test="$dec-value = 15">
<xsl:value-of select="'F'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$dec-value"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="GetTabColorIndex">
<xsl:param name="SheetColor"/>
<xsl:for-each select="key('config', 'TabColor')[not(.=preceding::config:config-item)]">
<xsl:sort select="." />
<xsl:variable name="tmpColor" select="."/>
<xsl:if test=". = $SheetColor" >
<xsl:value-of select="56 - position()"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template match="office:body">
<!-- office:body table:table children are spreadsheets -->
<xsl:apply-templates />
</xsl:template>
<xsl:template match="office:spreadsheet">
<xsl:apply-templates />
</xsl:template>
<!-- office:body table:table children are spreadsheets -->
<xsl:template match="office:spreadsheet/table:table">
<xsl:element name="ss:Worksheet">
<xsl:variable name="TableName">
<xsl:value-of select="@table:name" />
</xsl:variable>
<xsl:attribute name="ss:Name">
<xsl:value-of select="$TableName" />
</xsl:attribute>
<xsl:call-template name="table:table" />
<xsl:element name="x:WorksheetOptions">
<xsl:if test="key('config', 'ShowGrid') = 'false'">
<xsl:element name="x:DoNotDisplayGridlines" />
</xsl:if>
<xsl:if test="key('config', 'HasColumnRowHeaders') = 'false'">
<xsl:element name="x:DoNotDisplayHeadings" />
</xsl:if>
<xsl:if test="key('config', 'IsOutlineSymbolsSet') = 'false'">
<xsl:element name="x:DoNotDisplayOutline" />
</xsl:if>
<xsl:if test="key('config', 'ShowZeroValues') = 'false'">
<xsl:element name="x:DoNotDisplayZeros" />
</xsl:if>
<xsl:if test="/*/office:settings/config:config-item-set/config:config-item-map-indexed/config:config-item-map-entry/config:config-item-map-named/config:config-item-map-entry[@config:name=$TableName]/config:config-item[@config:name='TabColor']">
<xsl:element name="x:TabColorIndex">
<xsl:variable name="TabColorIndex">
<xsl:call-template name="GetTabColorIndex">
<xsl:with-param name="SheetColor" select="/*/office:settings/config:config-item-set/config:config-item-map-indexed/config:config-item-map-entry/config:config-item-map-named/config:config-item-map-entry[@config:name=$TableName]/config:config-item[@config:name='TabColor']"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$TabColorIndex"/>
</xsl:element>
</xsl:if>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="table:decls" mode="ExcelWorkbook">
<xsl:apply-templates mode="ExcelWorkbook" />
</xsl:template>
<xsl:template match="table:calculation-settings" mode="ExcelWorkbook">
<xsl:if test="table:precision-as-shown">
<x:PrecisionAsDisplayed/>
</xsl:if>
<xsl:if test="table:null-date/@office:date-value='1904-01-01'">
<x:Date1904/>
</xsl:if>
<xsl:apply-templates select="table:iteration" />
</xsl:template>
<xsl:template match="table:iteration" mode="ExcelWorkbook">
<xsl:element name="x:ExcelWorkbook">
<xsl:if test="@table:status = 'enable'">
<x:Iteration/>
</xsl:if>
<xsl:if test="@table:steps">
<xsl:element name="x:MaxIterations">
<xsl:value-of select="@table:steps" />
</xsl:element>
</xsl:if>
<xsl:if test="@table:maximum-difference">
<xsl:element name="x:MaxChange">
<xsl:value-of select="@table:maximum-difference" />
</xsl:element>
</xsl:if>
</xsl:element>
</xsl:template>
</xsl:stylesheet>

View File

@@ -0,0 +1,386 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--***********************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
***********************************************************-->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dom="http://www.w3.org/2001/xml-events"
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
xmlns:math="http://www.w3.org/1998/Math/MathML"
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:ooo="http://openoffice.org/2004/office"
xmlns:oooc="http://openoffice.org/2004/calc"
xmlns:ooow="http://openoffice.org/2004/writer"
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible: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:xlink="http://www.w3.org/1999/xlink"
xmlns:xt="http://www.jclark.com/xt"
xmlns:common="http://exslt.org/common"
xmlns:xalan="http://xml.apache.org/xalan"
xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:c="urn:schemas-microsoft-com:office:component:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:x2="http://schemas.microsoft.com/office/excel/2003/xml" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exclude-result-prefixes="chart config dc dom dr3d draw fo form math meta number office ooo oooc ooow script style svg table text xlink xt common xalan">
<xsl:variable name="namespace-html" select="'http://www.w3.org/TR/REC-html40'" />
<xsl:template match="@table:style-name | @table:default-cell-style-name">
<xsl:if test="not(name() = 'Default')">
<xsl:attribute name="ss:StyleID">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:if>
</xsl:template>
<xsl:key match="table:table-cell" name="getCellByStyle" use="@table:style-name"/>
<xsl:template match="@table:style-name" mode="table-row">
<!-- only row styles used by cells are exported,
as usual row style properties are already written as row attributes -->
<xsl:if test="key('getCellByStyle', '.')">
<xsl:attribute name="ss:StyleID">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:if>
</xsl:template>
<xsl:template name="style-and-contents">
<xsl:param name="cellStyleName" />
<!-- WorkAround of Excel2003 issue:
Styles from the CellStyle will not be inherited to HTML content (e.g. Colour style).
-->
<xsl:choose>
<xsl:when test="@text:style-name">
<xsl:variable name="styles">
<xsl:copy-of select="key('styles', @text:style-name)/*" />
<xsl:copy-of select="key('styles', $cellStyleName)/*" />
</xsl:variable>
<xsl:choose>
<xsl:when test="function-available('xalan:nodeset')">
<xsl:call-template name="create-nested-format-tags">
<xsl:with-param name="styles" select="xalan:nodeset($styles)" />
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:when>
<xsl:when test="function-available('xt:node-set')">
<xsl:call-template name="create-nested-format-tags">
<xsl:with-param name="styles" select="xt:node-set($styles)" />
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:when>
<xsl:when test="function-available('common:node-set')">
<xsl:call-template name="create-nested-format-tags">
<xsl:with-param name="styles" select="common:node-set($styles)" />
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">The required node-set function was not found!</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="@table:style-name">
<xsl:variable name="styles">
<xsl:copy-of select="key('styles', @text:style-name)/*" />
<xsl:copy-of select="key('styles', $cellStyleName)/*" />
</xsl:variable>
<xsl:choose>
<xsl:when test="function-available('xalan:nodeset')">
<xsl:call-template name="create-nested-format-tags">
<xsl:with-param name="styles" select="xalan:nodeset($styles)" />
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:when>
<xsl:when test="function-available('xt:node-set')">
<xsl:call-template name="create-nested-format-tags">
<xsl:with-param name="styles" select="xt:node-set($styles)" />
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:when>
<xsl:when test="function-available('common:node-set')">
<xsl:call-template name="create-nested-format-tags">
<xsl:with-param name="styles" select="common:node-set($styles)" />
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">The required node-set function was not found!</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates>
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- *********************************** -->
<!-- *** creating nested format tags *** -->
<!-- *********************************** -->
<!-- Bold -->
<xsl:template name="create-nested-format-tags">
<xsl:param name="styles" />
<xsl:param name="cellStyleName" />
<xsl:choose>
<xsl:when test="$styles/*/@fo:font-weight = 'bold' or $styles/*/@fo:font-weight = 'bolder'">
<xsl:element namespace="{$namespace-html}" name="B">
<xsl:call-template name="italic">
<xsl:with-param name="styles" select="$styles" />
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="italic">
<xsl:with-param name="styles" select="$styles" />
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Italic -->
<xsl:template name="italic">
<xsl:param name="styles" />
<xsl:param name="cellStyleName" />
<xsl:choose>
<xsl:when test="$styles/*/@fo:font-style = 'italic' or $styles/*/@fo:font-style = 'oblique'">
<xsl:element namespace="{$namespace-html}" name="I">
<xsl:call-template name="underline">
<xsl:with-param name="styles" select="$styles" />
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="underline">
<xsl:with-param name="styles" select="$styles" />
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Underline -->
<xsl:template name="underline">
<xsl:param name="styles" />
<xsl:param name="cellStyleName" />
<xsl:choose>
<xsl:when test="$styles/*/@style:text-underline-type and not($styles/*/@style:text-underline-type = 'none')">
<xsl:element namespace="{$namespace-html}" name="U">
<xsl:call-template name="strikethrough">
<xsl:with-param name="styles" select="$styles" />
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="strikethrough">
<xsl:with-param name="styles" select="$styles" />
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- strikethrough -->
<xsl:template name="strikethrough">
<xsl:param name="styles" />
<xsl:param name="cellStyleName" />
<xsl:choose>
<xsl:when test="$styles/*/@style:text-line-through-style and not($styles/*/@style:text-line-through-style = 'none')">
<xsl:element namespace="{$namespace-html}" name="S">
<xsl:call-template name="super-subscript">
<xsl:with-param name="styles" select="$styles" />
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="super-subscript">
<xsl:with-param name="styles" select="$styles" />
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- superscript & subscript -->
<xsl:template name="super-subscript">
<xsl:param name="styles" />
<xsl:param name="cellStyleName" />
<xsl:choose>
<xsl:when test="$styles/*/@style:text-position">
<xsl:variable name="textPosition" select="number(substring-before($styles/*/@style:text-position, '% '))" />
<xsl:choose>
<xsl:when test="$textPosition &gt; 0">
<xsl:element namespace="{$namespace-html}" name="Sup">
<xsl:call-template name="align">
<xsl:with-param name="styles" select="$styles" />
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:element>
</xsl:when>
<xsl:when test="$textPosition &lt; 0">
<xsl:element namespace="{$namespace-html}" name="Sub">
<xsl:call-template name="align">
<xsl:with-param name="styles" select="$styles" />
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="align">
<xsl:with-param name="styles" select="$styles" />
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="align">
<xsl:with-param name="styles" select="$styles" />
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Alignment - normally called by strikethrough, but no DIV elements in HTML -->
<xsl:template name="align">
<xsl:param name="styles" />
<xsl:param name="cellStyleName" />
<xsl:choose>
<xsl:when test="$styles/*/@fo:font-align">
<xsl:element namespace="{$namespace-html}" name="DIV">
<xsl:attribute name="html:style">
<xsl:choose>
<xsl:when test="$styles/*/@fo:font-align = 'start'">
<xsl:text>text-align:left;</xsl:text>
</xsl:when>
<xsl:when test="$styles/*/@fo:font-align = 'end'">
<xsl:text>text-align:right;</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>text-align:center;</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:call-template name="font">
<xsl:with-param name="styles" select="$styles" />
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="font">
<xsl:with-param name="styles" select="$styles" />
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Font (size and color) -->
<xsl:template name="font">
<xsl:param name="styles" />
<xsl:param name="cellStyleName" />
<xsl:choose>
<xsl:when test="$styles/*/@style:font-name or
$styles/*/@fo:font-size or
$styles/*/@fo:color">
<xsl:element namespace="{$namespace-html}" name="Font">
<xsl:if test="$styles/*/@style:font-name">
<xsl:attribute name="html:Face">
<xsl:value-of select="$styles/*/@style:font-name" />
</xsl:attribute>
</xsl:if>
<xsl:if test="$styles/*/@fo:color">
<xsl:attribute name="html:Color">
<xsl:value-of select="$styles/*/@fo:color" />
</xsl:attribute>
</xsl:if>
<xsl:if test="$styles/*/@fo:font-size">
<!-- WORKAROUND TO EXCEL2003 issue where nested FONT elements with size attributes result in unloadable documents -->
<!-- Only create size attribute if parent do not have already one -->
<!--<xsl:choose>
<xsl:when test="not(key('styles', parent::*/@text:style-name)/*/@fo:font-size)"> -->
<xsl:if test="not(key('styles', parent::*/@text:style-name)/*/@fo:font-size)">
<xsl:attribute name="html:Size">
<xsl:call-template name="convert2pt">
<xsl:with-param name="value" select="$styles/*/@fo:font-size" />
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:attribute>
</xsl:if>
<!--</xsl:when>
<xsl:otherwise>
<xsl:message>Due Excel issue we have to neglect size from @text:style-name '<xsl:value-of select="@text:style-name"/>'!</xsl:message>
</xsl:otherwise>
</xsl:choose>-->
</xsl:if>
<!-- get the embedded content -->
<xsl:apply-templates>
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:apply-templates>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<!-- get the embedded content -->
<xsl:apply-templates>
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

View File

@@ -0,0 +1,691 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--***********************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
***********************************************************-->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dom="http://www.w3.org/2001/xml-events"
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
xmlns:math="http://www.w3.org/1998/Math/MathML"
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:ooo="http://openoffice.org/2004/office"
xmlns:oooc="http://openoffice.org/2004/calc"
xmlns:ooow="http://openoffice.org/2004/writer"
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible: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:xlink="http://www.w3.org/1999/xlink"
xmlns:xt="http://www.jclark.com/xt"
xmlns:common="http://exslt.org/common"
xmlns:xalan="http://xml.apache.org/xalan"
xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:c="urn:schemas-microsoft-com:office:component:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:x2="http://schemas.microsoft.com/office/excel/2003/xml" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exclude-result-prefixes="chart config dc dom dr3d draw fo form math meta number office ooo oooc ooow script style svg table text xlink xt common xalan">
<!-- Used in case of 'style:map', conditional formatting, where a style references to another -->
<xsl:key name="styles" match="/*/office:styles/style:style | /*/office:automatic-styles/style:style" use="@style:name" />
<!--
Mapping of OOo style:name and style:family to excel ss:ID
Styles form style:style map from style:name to ss:Name
style:parent-style map to ss:Parent
-->
<!-- default styles of the application
<xsl:template match="style:default-style" mode="styles" >
<xsl:call-template name="style:style">
<xsl:with-param name="styleName" select="'Default'" />
</xsl:call-template>
</xsl:template>
-->
<xsl:template match="style:style" mode="styles">
<xsl:param name="isAutomatic" />
<xsl:param name="styleName" select="@style:name" />
<xsl:param name="styleParentName" select="@style:parent-style-name" />
<!-- only row styles used by cells are exported,
as usual row style properties are already exported as row attributes -->
<xsl:if test="not(@style:family='table-row') or @style:family='table-row' and key('getCellByStyle', '.')">
<xsl:element name="Style">
<xsl:attribute name="ss:ID">
<!-- neglecting that a style is only unique in conjunction with it's family name -->
<xsl:value-of select="@style:name" />
</xsl:attribute>
<xsl:choose>
<xsl:when test="not($isAutomatic)">
<xsl:choose>
<xsl:when test="@style:display-name">
<xsl:attribute name="ss:Name"><xsl:value-of select="@style:display-name"/></xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="ss:Name"><xsl:value-of select="@style:name" /></xsl:attribute>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<!-- when a non-allowed parent style is found
(in spreadsheetml no style with ss:Name is able to have a ss:Parent) -->
<xsl:when test="@style:parent-style-name">
<!-- styles have to be merged (flatting heritance tree) -->
<xsl:variable name="stylePropertiesContainer">
<xsl:call-template name="merge-all-parent-styles">
<xsl:with-param name="currentStyle" select="." />
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="function-available('xalan:nodeset')">
<xsl:call-template name="write-style-properties">
<xsl:with-param name="styleProperties" select="xalan:nodeset($stylePropertiesContainer)/*" />
</xsl:call-template>
</xsl:when>
<xsl:when test="function-available('common:node-set')">
<xsl:call-template name="write-style-properties">
<xsl:with-param name="styleProperties" select="common:node-set($stylePropertiesContainer)/*" />
</xsl:call-template>
</xsl:when>
<xsl:when test="function-available('xt:node-set')">
<xsl:call-template name="write-style-properties">
<xsl:with-param name="styleProperties" select="xt:node-set($stylePropertiesContainer)/*" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">WARNING: The required node set function was not found!</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="write-style-properties" />
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<!-- automatic styles are implicit inherting from a style called 'Default',
furthermore nor in spreadsheetml nor in OpenDocument automatic styles are able to inherit from each other -->
<xsl:choose>
<xsl:when test="@style:parent-style-name and not(@style:parent-style-name = 'Default')">
<xsl:attribute name="ss:Parent"><xsl:value-of select="@style:parent-style-name" /></xsl:attribute>
</xsl:when>
</xsl:choose>
<xsl:call-template name="write-style-properties" />
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:if>
</xsl:template>
<!-- resolving the style inheritance by starting from uppermost parent and
overriding exisiting style properties by new found child properties -->
<xsl:template name="merge-all-parent-styles">
<xsl:param name="currentStyle" />
<xsl:choose>
<!-- in case of a parent, styles have to be merged (flatting heritance tree) -->
<xsl:when test="$currentStyle/@style:parent-style-name">
<!-- collect parent style properties -->
<xsl:variable name="parentStyleContainer">
<!-- take a look if the parent style has a parent himself -->
<xsl:call-template name="merge-all-parent-styles" >
<xsl:with-param name="currentStyle" select="key('styles', $currentStyle/@style:parent-style-name)" />
</xsl:call-template>
</xsl:variable>
<xsl:choose>
<xsl:when test="function-available('xalan:nodeset')">
<xsl:call-template name="merge-style-properties">
<xsl:with-param name="childStyleContainer" select="$currentStyle" />
<xsl:with-param name="parentStyleContainer" select="xalan:nodeset($parentStyleContainer)" />
</xsl:call-template>
</xsl:when>
<xsl:when test="function-available('common:node-set')">
<xsl:call-template name="merge-style-properties">
<xsl:with-param name="childStyleContainer" select="$currentStyle" />
<xsl:with-param name="parentStyleContainer" select="common:node-set($parentStyleContainer)" />
</xsl:call-template>
</xsl:when>
<xsl:when test="function-available('xt:node-set')">
<xsl:call-template name="merge-style-properties">
<xsl:with-param name="childStyleContainer" select="$currentStyle" />
<xsl:with-param name="parentStyleContainer" select="xt:node-set($parentStyleContainer)" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:message terminate="yes">WARNING: The required node-set function was not found!</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<!-- called for top parents (or styles without parents) -->
<xsl:otherwise>
<xsl:copy-of select="$currentStyle/*"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="merge-style-properties">
<xsl:param name="childStyleContainer" />
<xsl:param name="parentStyleContainer" />
<xsl:choose>
<xsl:when test="$parentStyleContainer/*">
<xsl:apply-templates select="$parentStyleContainer/*" mode="inheritance">
<xsl:with-param name="childStyleContainer" select="$childStyleContainer" />
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$childStyleContainer/*"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="*" mode="inheritance">
<xsl:param name="childStyleContainer" />
<!-- create an element named equal to the current properties parent element (e.g. style:table-cell-properties) -->
<xsl:element name="{name()}" namespace="urn:oasis:names:tc:opendocument:xmlns:style:1.0">
<!-- attributes will be automatically replaced -->
<xsl:copy-of select="@*" />
<xsl:copy-of select="$childStyleContainer/*[name() = name(current() )]/@*"/>
<!-- elements are not needed yet, will be neglected for simplicity reasons -->
</xsl:element>
</xsl:template>
<xsl:key match="/*/office:styles/number:date-style |
/*/office:styles/number:time-style |
/*/office:styles/number:number-style |
/*/office:styles/number:percentage-style |
/*/office:styles/number:currency-style |
/*/office:automatic-styles/number:date-style |
/*/office:automatic-styles/number:time-style |
/*/office:automatic-styles/number:number-style |
/*/office:automatic-styles/number:percentage-style |
/*/office:automatic-styles/number:currency-style" name="number-style" use="@style:name" />
<xsl:template name="write-style-properties">
<xsl:param name="styleProperties" select="key('styles', @style:name)/*" />
<xsl:call-template name="Alignment">
<xsl:with-param name="styleProperties" select="$styleProperties" />
</xsl:call-template>
<xsl:call-template name="Border">
<xsl:with-param name="styleProperties" select="$styleProperties" />
</xsl:call-template>
<xsl:call-template name="Font">
<xsl:with-param name="styleProperties" select="$styleProperties" />
<xsl:with-param name="styleParentName" select="@style:parent-style-name" />
</xsl:call-template>
<xsl:call-template name="Interior">
<xsl:with-param name="styleProperties" select="$styleProperties" />
</xsl:call-template>
<xsl:call-template name="NumberFormat">
<xsl:with-param name="styleProperties" select="$styleProperties" />
</xsl:call-template>
</xsl:template>
<!-- context is element 'style:style' -->
<xsl:template name="NumberFormat">
<xsl:if test="@style:data-style-name">
<xsl:variable name="numberStyleName" select="@style:data-style-name" />
<xsl:variable name="numberStyle" select="key('number-style', $numberStyleName)" />
<xsl:element name="NumberFormat">
<xsl:attribute name="ss:Format">
<xsl:choose>
<xsl:when test="not($numberStyle/node())">
<!-- Excel2003sp1 issue: 'General' and 'General Number' is not supported -->
<xsl:text>General</xsl:text>
</xsl:when>
<xsl:when test="name($numberStyle) = 'number:number-style'">
<xsl:choose>
<xsl:when test="$numberStyle/number:scientific-number">
<xsl:text>Scientific</xsl:text>
</xsl:when>
<!-- Excel2003sp1 issue: 'General Number' not supported -->
<xsl:when test="$numberStyle/number:number/@number:decimal-places and
$numberStyle/number:number/@number:decimal-places='0'">
<xsl:text>General</xsl:text>
</xsl:when>
<xsl:when test="$numberStyle/number:text">
<xsl:choose>
<xsl:when test="$numberStyle/number:text = 'No' or $numberStyle/number:text = 'Nein'">
<xsl:text>Yes/No</xsl:text>
</xsl:when>
<xsl:when test="$numberStyle/number:text = 'False' or $numberStyle/number:text = 'Falsch'">
<xsl:text>True/False</xsl:text>
</xsl:when>
<xsl:when test="$numberStyle/number:text = 'Off' or $numberStyle/number:text = 'Aus'">
<xsl:text>On/Off</xsl:text>
</xsl:when>
<!-- Excel2003sp1 issue: currency is saved as 'float' -->
<xsl:when test="$numberStyle/number:currency-symbol">
<xsl:choose>
<xsl:when test="contains($numberStyle/number:currency-symbol, '€')">
<xsl:text>Euro Currency</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>Currency</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<!-- Excel2003sp1 issue: 'Currency' is saved as 'float' -->
<xsl:when test="contains($numberStyle/number:text, '$')">
<xsl:text>Currency</xsl:text>
</xsl:when>
<!-- OASIS XML adapation -->
<xsl:otherwise>
<xsl:text>General</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$numberStyle/number:grouping">
<xsl:text>Standard</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>Fixed</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="name($numberStyle) = 'number:time-style'">
<xsl:choose>
<xsl:when test="$numberStyle/number:am-pm">
<xsl:choose>
<xsl:when test="$numberStyle/number:seconds">
<xsl:text>Long Time</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>Medium Time</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:text>Short Time</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="name($numberStyle) = 'number:percentage-style'">
<xsl:text>Percent</xsl:text>
</xsl:when>
<xsl:when test="name($numberStyle) = 'number:currency-style'">
<xsl:choose>
<xsl:when test="contains($numberStyle/number:currency-symbol, '€')">
<xsl:text>Euro Currency</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>Currency</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:choose>
<xsl:when test="$numberStyle/number:month">
<xsl:choose>
<xsl:when test="$numberStyle/number:month/@number:textual and
$numberStyle/number:month/@number:textual=true()">
<xsl:text>Medium Date</xsl:text>
<!-- Excel2003 sp1 issue: No difference between 'Long Date' and 'Medium Date' -->
</xsl:when>
<xsl:when test="$numberStyle/number:hours">
<xsl:text>General Date</xsl:text>
</xsl:when>
<xsl:when test="$numberStyle/number:year/@number:style and
$numberStyle/number:year/@number:style='long'">
<xsl:text>Short Date</xsl:text>
</xsl:when>
<!-- OASIS XML adapation -->
<xsl:otherwise>
<xsl:text>Short Date</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<!-- OASIS XML adapation -->
<xsl:otherwise>
<xsl:text>General</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:element>
</xsl:if>
</xsl:template>
<xsl:template name="Alignment">
<xsl:param name="styleProperties" />
<!-- An empty Alignment element, might overwrite parents setting by
the default attributes -->
<xsl:if test="$styleProperties/@fo:text-align or
$styleProperties/@style:vertical-align or
$styleProperties/@fo:wrap-option or
$styleProperties/@fo:margin-left or
$styleProperties/@style:rotation-angle or
$styleProperties/@style:direction">
<xsl:element name="Alignment">
<xsl:if test="$styleProperties/@fo:text-align">
<xsl:attribute name="ss:Horizontal">
<xsl:choose>
<xsl:when test="$styleProperties/@fo:text-align = 'center'">Center</xsl:when>
<xsl:when test="$styleProperties/@fo:text-align = 'end'">Right</xsl:when>
<xsl:when test="$styleProperties/@fo:text-align = 'justify'">Justify</xsl:when>
<xsl:otherwise>Left</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:if>
<xsl:if test="$styleProperties/@style:vertical-align">
<xsl:attribute name="ss:Vertical">
<xsl:choose>
<xsl:when test="$styleProperties/@style:vertical-align = 'top'">Top</xsl:when>
<xsl:when test="$styleProperties/@style:vertical-align = 'bottom'">Bottom</xsl:when>
<xsl:when test="$styleProperties/@style:vertical-align = 'middle'">Center</xsl:when>
<xsl:otherwise>Automatic</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:if>
<xsl:if test="$styleProperties/@fo:wrap-option = 'wrap'">
<xsl:attribute name="ss:WrapText">1</xsl:attribute>
</xsl:if>
<xsl:if test="$styleProperties/@fo:margin-left">
<xsl:attribute name="ss:Indent">
<xsl:variable name="margin">
<xsl:call-template name="convert2pt">
<xsl:with-param name="value" select="$styleProperties/@fo:margin-left" />
<xsl:with-param name="rounding-factor" select="1" />
</xsl:call-template>
</xsl:variable>
<!-- one ss:Indent is equal to 10 points -->
<xsl:value-of select="number($margin) div 10"/>
</xsl:attribute>
</xsl:if>
<!-- Excel is only able to rotate between 90 and -90 degree (inclusive).
Other degrees will be mapped by 180 degrees -->
<xsl:if test="$styleProperties/@style:rotation-angle">
<xsl:attribute name="ss:Rotate">
<xsl:choose>
<xsl:when test="$styleProperties/@style:rotation-angle &gt; 90">
<xsl:choose>
<xsl:when test="$styleProperties/@style:rotation-angle &gt;= 270">
<xsl:value-of select="$styleProperties/@style:rotation-angle - 360" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$styleProperties/@style:rotation-angle - 180" />
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$styleProperties/@style:rotation-angle &lt; -90">
<xsl:choose>
<xsl:when test="$styleProperties/@style:rotation-angle &lt;= -270">
<xsl:value-of select="$styleProperties/@style:rotation-angle + 360" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$styleProperties/@style:rotation-angle + 180" />
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$styleProperties/@style:rotation-angle" />
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:if>
<xsl:if test="$styleProperties/@style:direction = 'ttb'">
<xsl:attribute name="ss:VerticalText">1</xsl:attribute>
</xsl:if>
</xsl:element>
</xsl:if>
</xsl:template>
<xsl:template name="Border">
<xsl:param name="styleProperties" />
<!-- An empty border element, might overwrite parents setting by
the default attributes -->
<xsl:if test="$styleProperties/@fo:border or
$styleProperties/@fo:border-bottom or
$styleProperties/@fo:border-left or
$styleProperties/@fo:border-right or
$styleProperties/@fo:border-top">
<xsl:element name="Borders">
<xsl:if test="$styleProperties/@fo:border-bottom and not($styleProperties/@fo:border-bottom = 'none')">
<xsl:element name="Border">
<xsl:attribute name="ss:Position">Bottom</xsl:attribute>
<xsl:call-template name="border-attributes">
<xsl:with-param name="border_properties" select="$styleProperties/@fo:border-bottom" />
</xsl:call-template>
</xsl:element>
</xsl:if>
<xsl:if test="$styleProperties/@fo:border-left and not($styleProperties/@fo:border-left = 'none')">
<xsl:element name="Border">
<xsl:attribute name="ss:Position">Left</xsl:attribute>
<xsl:call-template name="border-attributes">
<xsl:with-param name="border_properties" select="$styleProperties/@fo:border-left" />
</xsl:call-template>
</xsl:element>
</xsl:if>
<xsl:if test="$styleProperties/@fo:border-right and not($styleProperties/@fo:border-right = 'none')">
<xsl:element name="Border">
<xsl:attribute name="ss:Position">Right</xsl:attribute>
<xsl:call-template name="border-attributes">
<xsl:with-param name="border_properties" select="$styleProperties/@fo:border-right" />
</xsl:call-template>
</xsl:element>
</xsl:if>
<xsl:if test="$styleProperties/@fo:border-top and not($styleProperties/@fo:border-top = 'none')">
<xsl:element name="Border">
<xsl:attribute name="ss:Position">Top</xsl:attribute>
<xsl:call-template name="border-attributes">
<xsl:with-param name="border_properties" select="$styleProperties/@fo:border-top" />
</xsl:call-template>
</xsl:element>
</xsl:if>
<!-- write out all table border -->
<xsl:if test="$styleProperties/@fo:border and not($styleProperties/@fo:border = 'none')">
<xsl:element name="Border">
<xsl:attribute name="ss:Position">Bottom</xsl:attribute>
<xsl:call-template name="border-attributes">
<xsl:with-param name="border_properties" select="$styleProperties/@fo:border" />
</xsl:call-template>
</xsl:element>
<xsl:element name="Border">
<xsl:attribute name="ss:Position">Left</xsl:attribute>
<xsl:call-template name="border-attributes">
<xsl:with-param name="border_properties" select="$styleProperties/@fo:border" />
</xsl:call-template>
</xsl:element>
<xsl:element name="Border">
<xsl:attribute name="ss:Position">Right</xsl:attribute>
<xsl:call-template name="border-attributes">
<xsl:with-param name="border_properties" select="$styleProperties/@fo:border" />
</xsl:call-template>
</xsl:element>
<xsl:element name="Border">
<xsl:attribute name="ss:Position">Top</xsl:attribute>
<xsl:call-template name="border-attributes">
<xsl:with-param name="border_properties" select="$styleProperties/@fo:border" />
</xsl:call-template>
</xsl:element>
</xsl:if>
</xsl:element>
</xsl:if>
</xsl:template>
<xsl:template name="border-attributes">
<xsl:param name="border_properties" />
<xsl:variable name="border-width">
<xsl:call-template name="convert2cm">
<xsl:with-param name="value" select="substring-before($border_properties, ' ')" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="border-style" select="substring-before(substring-after($border_properties, ' '), ' ')" />
<xsl:variable name="border-color" select="substring-after(substring-after($border_properties, ' '), ' ')" />
<!--
<xsl:message>border-width:<xsl:value-of select="$border-width" /></xsl:message>
<xsl:message>border-style:<xsl:value-of select="$border-style" /></xsl:message>
<xsl:message>border-color:<xsl:value-of select="$border-color" /></xsl:message>
-->
<!-- Dash, Dot, DashDot, DashDotDot, SlantDashDot are not supported yet -->
<xsl:attribute name="ss:LineStyle">
<xsl:choose>
<xsl:when test="$border-style = 'none'">None</xsl:when>
<xsl:when test="$border-style = 'double'">Double</xsl:when>
<xsl:otherwise>Continuous</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="ss:Weight">
<xsl:choose>
<!-- 0: Hairline -->
<xsl:when test="$border-width &lt;= 0.002">0</xsl:when>
<!-- 1: Thin -->
<xsl:when test="$border-width &lt;= 0.035">1</xsl:when>
<!-- 2: Medium -->
<xsl:when test="$border-width &lt;= 0.088">2</xsl:when>
<!-- 3: Thick -->
<xsl:otherwise>3</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="ss:Color">
<xsl:choose>
<xsl:when test="$border-color"><xsl:value-of select="$border-color" /></xsl:when>
<xsl:otherwise>Automatic</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:template>
<xsl:template name="Font">
<xsl:param name="styleProperties" />
<xsl:param name="styleParentName" />
<!-- An empty font element, might overwrite parents setting by
the default attributes -->
<xsl:if test="$styleProperties/@style:font-weight or
$styleProperties/@fo:color or
$styleProperties/@style:font-name or
$styleProperties/@fo:font-style or
$styleProperties/@style:text-outline or
$styleProperties/@style:text-shadow or
$styleProperties/@style:font-size or
$styleProperties/@style:text-line-through-style or
$styleProperties/@style:text-underline-type or
$styleProperties/@style:text-underline-style or
$styleProperties/@style:text-position">
<xsl:element name="Font">
<xsl:call-template name="getParentBold">
<xsl:with-param name="styleProperties" select="$styleProperties" />
<xsl:with-param name="styleParentName" select="$styleParentName" />
</xsl:call-template>
<xsl:if test="$styleProperties/@fo:color">
<xsl:attribute name="ss:Color"><xsl:value-of select="$styleProperties/@fo:color" /></xsl:attribute>
</xsl:if>
<xsl:if test="$styleProperties/@style:font-name">
<xsl:attribute name="ss:FontName"><xsl:value-of select="$styleProperties/@style:font-name" /></xsl:attribute>
</xsl:if>
<xsl:if test="$styleProperties/@fo:font-style = 'italic'">
<xsl:attribute name="ss:Italic">1</xsl:attribute>
</xsl:if>
<xsl:if test="$styleProperties/@style:text-outline = 'true'">
<xsl:attribute name="ss:Outline">1</xsl:attribute>
</xsl:if>
<xsl:if test="$styleProperties/@style:text-shadow = 'shadow'">
<xsl:attribute name="ss:Shadow">1</xsl:attribute>
</xsl:if>
<xsl:if test="$styleProperties/@fo:font-size">
<xsl:attribute name="ss:Size">
<xsl:call-template name="convert2pt">
<xsl:with-param name="value" select="$styleProperties/@fo:font-size" />
</xsl:call-template>
</xsl:attribute>
</xsl:if>
<xsl:if test="$styleProperties/@style:text-line-through-style and $styleProperties/@style:text-line-through-style != 'none'">
<xsl:attribute name="ss:StrikeThrough">1</xsl:attribute>
</xsl:if>
<xsl:if test="($styleProperties/@style:text-underline-type and $styleProperties/@style:text-underline-type != 'none') or
($styleProperties/@style:text-underline-style and $styleProperties/@style:text-underline-style != 'none')">
<xsl:attribute name="ss:Underline">
<xsl:choose>
<xsl:when test="$styleProperties/@style:text-underline-type = 'double'">Double</xsl:when>
<xsl:otherwise>Single</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:if>
<xsl:if test="$styleProperties/@style:text-position">
<xsl:attribute name="ss:VerticalAlign">
<xsl:choose>
<xsl:when test="substring-before($styleProperties/@style:text-position, '% ') &gt; 0">Superscript</xsl:when>
<xsl:otherwise>Subscript</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:if>
</xsl:element>
</xsl:if>
</xsl:template>
<xsl:template name="Interior">
<xsl:param name="styleProperties" />
<xsl:if test="$styleProperties/@fo:background-color and not($styleProperties/@fo:background-color = 'transparent')">
<xsl:element name="Interior">
<xsl:attribute name="ss:Color">
<xsl:value-of select="$styleProperties/@fo:background-color" />
</xsl:attribute>
<!-- Background color (i.e. Interior/ss:Color) not shown without ss:Pattern (or with 'none')
Therefore a default is set -->
<xsl:attribute name="ss:Pattern">Solid</xsl:attribute>
</xsl:element>
</xsl:if>
</xsl:template>
<!-- Excel issue workaround: <Font ss:Bold="1"> is not inherited -->
<xsl:template name="getParentBold">
<xsl:param name="styleProperties" />
<xsl:param name="styleParentName" />
<xsl:param name="styleName" />
<xsl:if test="$styleParentName and $styleParentName != $styleName">
<xsl:choose>
<xsl:when test="$styleProperties/@fo:font-weight = 'bold'">
<xsl:attribute name="ss:Bold">1</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="getParentBold">
<xsl:with-param name="styleProperties" select="key('styles', $styleParentName)/*" />
<xsl:with-param name="styleParentName" select="key('styles', $styleParentName)/@style:parent-style-name" />
<xsl:with-param name="styleName" select="$styleParentName" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

View File

@@ -0,0 +1,933 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--***********************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
***********************************************************-->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:dom="http://www.w3.org/2001/xml-events"
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
xmlns:math="http://www.w3.org/1998/Math/MathML"
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:ooo="http://openoffice.org/2004/office"
xmlns:oooc="http://openoffice.org/2004/calc"
xmlns:ooow="http://openoffice.org/2004/writer"
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible: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:xlink="http://www.w3.org/1999/xlink"
xmlns:xt="http://www.jclark.com/xt"
xmlns:common="http://exslt.org/common"
xmlns:xalan="http://xml.apache.org/xalan"
xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:c="urn:schemas-microsoft-com:office:component:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:x2="http://schemas.microsoft.com/office/excel/2003/xml" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exclude-result-prefixes="chart config dc dom dr3d draw fo form math meta number office ooo oooc ooow script style svg table text xlink xt common xalan">
<!-- ************** -->
<!-- *** Table *** -->
<!-- ************** -->
<!-- check existence of default cell style -->
<xsl:variable name="firstDefaultCellStyle" select="descendant::table:table-column/@table:default-cell-style-name" />
<xsl:template match="table:table" name="table:table">
<xsl:element name="Table">
<xsl:apply-templates select="@table:style-name" />
<!-- find all columns in the table -->
<xsl:variable name="columnNodes" select="descendant::table:table-column" />
<!-- calculate the overall column amount -->
<xsl:variable name="maxColumnNo">
<xsl:choose>
<xsl:when test="$columnNodes/@table:number-columns-repeated">
<xsl:value-of select="count($columnNodes)
+ number(sum($columnNodes/@table:number-columns-repeated))
- count($columnNodes/@table:number-columns-repeated)" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="count($columnNodes)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- create columns -->
<xsl:apply-templates select="$columnNodes[1]">
<xsl:with-param name="columnNodes" select="$columnNodes" />
<xsl:with-param name="maxColumnNo" select="$maxColumnNo" />
</xsl:apply-templates>
<!-- create rows -->
<xsl:choose>
<xsl:when test="not($columnNodes/@table:number-columns-repeated)">
<xsl:call-template name="optimized-row-handling">
<xsl:with-param name="rowNodes" select="descendant::table:table-row" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- To be able to match from a cell to the corresponding column to match @table:default-cell-style-name,
the repeated columns are being resolved by copying them in a helper variable -->
<xsl:variable name="columnNodes-RTF">
<xsl:for-each select="$columnNodes">
<xsl:call-template name="adding-column-styles-entries" />
</xsl:for-each>
</xsl:variable>
<xsl:choose>
<xsl:when test="function-available('xalan:nodeset')">
<xsl:call-template name="optimized-row-handling">
<xsl:with-param name="rowNodes" select="descendant::table:table-row" />
<xsl:with-param name="columnNodes" select="xalan:nodeset($columnNodes-RTF)" />
</xsl:call-template>
</xsl:when>
<xsl:when test="function-available('common:node-set')">
<xsl:call-template name="optimized-row-handling">
<xsl:with-param name="rowNodes" select="descendant::table:table-row" />
<xsl:with-param name="columnNodes" select="common:node-set($columnNodes-RTF)" />
</xsl:call-template>
</xsl:when>
<xsl:when test="function-available('xt:node-set')">
<xsl:call-template name="optimized-row-handling">
<xsl:with-param name="rowNodes" select="descendant::table:table-row" />
<xsl:with-param name="columnNodes" select="xt:node-set($columnNodes-RTF)" />
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:template>
<!-- **************** -->
<!-- *** Columns *** -->
<!-- **************** -->
<xsl:template match="table:table-column">
<xsl:param name="columnNodes" />
<xsl:param name="currentColumnNumber" select="1" />
<xsl:param name="setIndex" select="false()" />
<xsl:param name="maxColumnNo" />
<xsl:element name="Column">
<xsl:if test="@table:visibility = 'collapse' or @table:visibility = 'filter'">
<xsl:attribute name="ss:Hidden">1</xsl:attribute>
</xsl:if>
<xsl:if test="@table:number-columns-repeated">
<xsl:attribute name="ss:Span">
<xsl:value-of select="@table:number-columns-repeated - 1" />
</xsl:attribute>
</xsl:if>
<xsl:if test="$setIndex">
<xsl:attribute name="ss:Index">
<xsl:value-of select="$currentColumnNumber" />
</xsl:attribute>
</xsl:if>
<xsl:choose>
<xsl:when test="@style:use-optimal-column-width = 'true'">
<xsl:attribute name="ss:AutoFitWidth">1</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="width" select="key('styles', @table:style-name)/style:table-column-properties/@style:column-width" />
<xsl:if test="$width">
<xsl:attribute name="ss:Width">
<!-- using the absolute width in point -->
<xsl:call-template name="convert2pt">
<xsl:with-param name="value" select="$width" />
</xsl:call-template>
</xsl:attribute>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="@table:number-columns-repeated">
<xsl:attribute name="ss:Span">
<xsl:value-of select="@table:number-columns-repeated - 1" />
</xsl:attribute>
</xsl:if>
</xsl:element>
<xsl:variable name="columnNumber">
<xsl:choose>
<xsl:when test="@table:number-columns-repeated">
<xsl:value-of select="$currentColumnNumber + @table:number-columns-repeated"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$currentColumnNumber"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:if test="$columnNumber &lt; $maxColumnNo">
<xsl:variable name="nextColumnNodes" select="$columnNodes[position() != 1]" />
<xsl:choose>
<xsl:when test="@table:number-columns-repeated">
<xsl:apply-templates select="$nextColumnNodes[1]">
<xsl:with-param name="columnNodes" select="$nextColumnNodes" />
<xsl:with-param name="currentColumnNumber" select="$columnNumber" />
<xsl:with-param name="maxColumnNo" select="$maxColumnNo" />
<xsl:with-param name="setIndex" select="true()" />
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="$nextColumnNodes[1]">
<xsl:with-param name="columnNodes" select="$nextColumnNodes" />
<xsl:with-param name="currentColumnNumber" select="$columnNumber + 1" />
<xsl:with-param name="maxColumnNo" select="$maxColumnNo" />
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
<!-- current node is a table:table-column -->
<xsl:template name="adding-column-styles-entries">
<xsl:choose>
<xsl:when test="not(@table:number-columns-repeated and @table:number-columns-repeated > 1)">
<!-- writes an entry of a column in the columns-variable -->
<xsl:copy-of select="." />
</xsl:when>
<xsl:otherwise>
<!-- repeated colums will be written explicit several times in the variable-->
<xsl:call-template name="repeat-adding-table-column">
<xsl:with-param name="numberColumnsRepeated" select="@table:number-columns-repeated" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- current node is a table:table-column -->
<!-- dublicates column elements in case of column-repeated attribute -->
<xsl:template name="repeat-adding-table-column">
<xsl:param name="table:table-column" />
<xsl:param name="numberColumnsRepeated" />
<xsl:choose>
<xsl:when test="$numberColumnsRepeated > 1">
<!-- writes an entry of a column in the columns-variable -->
<xsl:copy-of select="." />
<!-- repeat calling this method until all elements written out -->
<xsl:call-template name="repeat-adding-table-column">
<xsl:with-param name="numberColumnsRepeated" select="$numberColumnsRepeated - 1" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- writes an entry of a column in the columns-variable -->
<xsl:copy-of select="." />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- ************* -->
<!-- *** Rows *** -->
<!-- ************* -->
<!-- Recursions are much faster when the stack size is small -->
<xsl:template name="optimized-row-handling">
<xsl:param name="rowNodes" />
<xsl:param name="columnNodes" />
<xsl:param name="offset" select="0"/>
<xsl:param name="threshold" select="10"/>
<xsl:variable name="rowCount" select="count($rowNodes)"/>
<xsl:choose>
<xsl:when test="$rowCount &lt;= $threshold">
<xsl:apply-templates select="$rowNodes[1]">
<xsl:with-param name="rowNodes" select="$rowNodes" />
<xsl:with-param name="offset" select="$offset" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="rowCountHalf" select="floor($rowCount div 2)"/>
<xsl:variable name="rowNodesSetA" select="$rowNodes[position() &lt;= $rowCountHalf]"/>
<xsl:variable name="rowNodesSetB" select="$rowNodes[position() &gt; $rowCountHalf]"/>
<!-- to keep track of the rownumber, the repeteated rows have to kept into accounts -->
<xsl:variable name="rowsCreatedByRepetition">
<xsl:choose>
<xsl:when test="$rowNodesSetA/@table:number-rows-repeated">
<xsl:value-of select="number(sum($rowNodesSetA/@table:number-rows-repeated))
- count($rowNodesSetA/@table:number-rows-repeated)" />
</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="$rowCountHalf &gt; $threshold">
<xsl:call-template name="optimized-row-handling">
<xsl:with-param name="rowNodes" select="$rowNodesSetA"/>
<xsl:with-param name="offset" select="$offset" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:call-template>
<xsl:call-template name="optimized-row-handling">
<xsl:with-param name="rowNodes" select="$rowNodesSetB"/>
<xsl:with-param name="offset" select="$offset + $rowCountHalf + $rowsCreatedByRepetition" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="$rowNodesSetA[1]">
<xsl:with-param name="rowNodes" select="$rowNodesSetA"/>
<xsl:with-param name="offset" select="$offset" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:apply-templates>
<xsl:apply-templates select="$rowNodesSetB[1]">
<xsl:with-param name="rowNodes" select="$rowNodesSetB" />
<xsl:with-param name="offset" select="$offset + $rowCountHalf + $rowsCreatedByRepetition" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--
Rows as "table:table-row" might be grouped in
"table:table-header-rows" or "table:table-row-group"
This row-tree will be traversed providing each Row with it's
calculatedRowPosition and earlierRowNumber.
By this repeated empty rows might be neglected in the spreadsheetml output,
as the following row will notice the 'gap' and provide @ss:Index,
which results in filling up the gap by a row without style and content.
In Excel created rows by ss:Index are 'default' rows.
-->
<xsl:template match="table:table-row">
<xsl:param name="earlierRowNumber" select="0" />
<xsl:param name="offset" />
<xsl:param name="calculatedRowPosition" select="$offset + 1" />
<xsl:param name="rowNodes" />
<xsl:param name="columnNodes" />
<xsl:choose>
<xsl:when test="@table:number-rows-repeated &gt; 1">
<xsl:call-template name="write-table-row">
<xsl:with-param name="earlierRowNumber" select="$earlierRowNumber" />
<xsl:with-param name="calculatedRowPosition" select="$calculatedRowPosition" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:call-template>
<xsl:if test="@table:number-rows-repeated &gt; 2 and (table:table-cell/@office:value-type or $firstDefaultCellStyle != '')">
<!-- In case a cell is being repeated, the cell will be created
in a variabel, which is as many times given out, as being repeated -->
<xsl:variable name="tableRow">
<xsl:call-template name="write-table-row">
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:call-template>
</xsl:variable>
<xsl:call-template name="optimized-row-repeating">
<xsl:with-param name="tableRow" select="$tableRow" />
<xsl:with-param name="repetition" select="@table:number-rows-repeated - 1" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:call-template>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="write-table-row">
<xsl:with-param name="earlierRowNumber" select="$earlierRowNumber" />
<xsl:with-param name="calculatedRowPosition" select="$calculatedRowPosition" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
<xsl:variable name="nextRowNodes" select="$rowNodes[position()!=1]" />
<xsl:choose>
<xsl:when test="@table:number-rows-repeated &gt; 1">
<xsl:apply-templates select="$nextRowNodes[1]">
<xsl:with-param name="earlierRowNumber" select="$calculatedRowPosition" />
<xsl:with-param name="calculatedRowPosition" select="$calculatedRowPosition + @table:number-rows-repeated" />
<xsl:with-param name="rowNodes" select="$nextRowNodes" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="$nextRowNodes[1]">
<xsl:with-param name="earlierRowNumber" select="$calculatedRowPosition" />
<xsl:with-param name="calculatedRowPosition" select="$calculatedRowPosition + 1" />
<xsl:with-param name="rowNodes" select="$nextRowNodes" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="write-table-row">
<xsl:param name="earlierRowNumber" select="0" />
<xsl:param name="calculatedRowPosition" select="1" />
<xsl:param name="columnNodes" />
<xsl:element name="Row">
<xsl:if test="@table:visibility = 'collapse' or @table:visibility = 'filter'">
<xsl:attribute name="ss:Hidden">1</xsl:attribute>
</xsl:if>
<xsl:if test="not($earlierRowNumber + 1 = $calculatedRowPosition)">
<xsl:attribute name="ss:Index"><xsl:value-of select="$calculatedRowPosition" /></xsl:attribute>
</xsl:if>
<!-- writing the style of the row -->
<xsl:apply-templates select="@table:style-name" mode="table-row" />
<xsl:variable name="rowProperties" select="key('styles', @table:style-name)/*" />
<xsl:if test="$rowProperties/@style:use-optimal-row-height = 'false'">
<!-- default is '1', therefore write only '0' -->
<xsl:attribute name="ss:AutoFitHeight">0</xsl:attribute>
</xsl:if>
<xsl:variable name="height" select="$rowProperties/@style:row-height" />
<xsl:if test="$height">
<xsl:attribute name="ss:Height">
<!-- using the absolute height in point -->
<xsl:call-template name="convert2pt">
<xsl:with-param name="value" select="$height" />
</xsl:call-template>
</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="table:table-cell[1]">
<xsl:with-param name="calculatedRowPosition" select="$calculatedRowPosition" />
<xsl:with-param name="cellNodes" select="table:table-cell" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:apply-templates>
</xsl:element>
</xsl:template>
<!-- Recursions are much faster when the stack size is small -->
<xsl:template name="optimized-row-repeating">
<xsl:param name="tableRow" />
<xsl:param name="repetition" />
<!-- resource optimation: instead of '1' it will be '1000' and the column is not full -->
<xsl:param name="thresholdmax" select="512"/>
<xsl:param name="thresholdmin" select="256"/>
<xsl:choose>
<xsl:when test="$repetition &lt;= $thresholdmax">
<xsl:copy-of select="$tableRow" />
<xsl:if test="$repetition &lt;= $thresholdmin">
<xsl:call-template name="optimized-row-repeating">
<xsl:with-param name="repetition" select="$repetition - 1"/>
<xsl:with-param name="tableRow" select="$tableRow" />
</xsl:call-template>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:if test="$repetition mod 2 = 1">
<xsl:copy-of select="$tableRow" />
</xsl:if>
<xsl:variable name="repetitionHalf" select="floor($repetition div 2)"/>
<xsl:call-template name="optimized-row-repeating">
<xsl:with-param name="repetition" select="$repetitionHalf"/>
<xsl:with-param name="tableRow" select="$tableRow" />
</xsl:call-template>
<xsl:call-template name="optimized-row-repeating">
<xsl:with-param name="repetition" select="$repetitionHalf"/>
<xsl:with-param name="tableRow" select="$tableRow" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- ************** -->
<!-- *** Cells *** -->
<!-- ************** -->
<!-- Table cells are able to be repeated by attribute in StarOffice,
but not in Excel. If more cells are repeated -->
<xsl:template name="table:table-cell" match="table:table-cell">
<xsl:param name="calculatedCellPosition" select="1" /><!-- the later table position of the current cell -->
<xsl:param name="calculatedRowPosition" /><!-- the later table position of the current row -->
<xsl:param name="setIndex" select="false()" /> <!-- if not '0' @ss:Index used for neglecting repeteated empty cells -->
<xsl:param name="repetition" select="@table:number-columns-repeated" /> <!-- used for explicit writen out cells -->
<xsl:param name="repetitionCellPosition" select="$calculatedCellPosition" /><!-- during repetition formula needs exact cell positioning -->
<xsl:param name="nextMatchedCellPosition"><!-- the later table position of the next cell -->
<xsl:choose>
<xsl:when test="not(@table:number-columns-repeated) and not(@table:number-columns-spanned)">
<xsl:value-of select="$calculatedCellPosition + 1" />
</xsl:when>
<xsl:when test="not(@table:number-columns-spanned)">
<xsl:value-of select="$calculatedCellPosition + @table:number-columns-repeated" />
</xsl:when>
<xsl:when test="not(@table:number-columns-repeated)">
<xsl:value-of select="$calculatedCellPosition + @table:number-columns-spanned" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$calculatedCellPosition + @table:number-columns-spanned * @table:number-columns-repeated" />
</xsl:otherwise>
</xsl:choose>
</xsl:param>
<xsl:param name="cellNodes" /><!-- cells to be handled -->
<xsl:param name="columnNodes" />
<xsl:choose>
<!-- in case a repetition took place -->
<xsl:when test="$repetition &gt; 0">
<xsl:choose>
<!-- In case of no cell content (text, subelements, attribute, except repeated style) the ss:Index could be used -->
<xsl:when test="not(text()) and not(*) and not(@*[name() != 'table:number-columns-repeated'])">
<xsl:choose>
<xsl:when test="count($cellNodes) = 1">
<xsl:call-template name="create-table-cell">
<xsl:with-param name="setIndex" select="true()" />
<xsl:with-param name="calculatedCellPosition" select="$nextMatchedCellPosition - 1" />
<xsl:with-param name="calculatedRowPosition" select="$calculatedRowPosition" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="$cellNodes[2]">
<xsl:with-param name="calculatedCellPosition" select="$nextMatchedCellPosition" />
<xsl:with-param name="calculatedRowPosition" select="$calculatedRowPosition" />
<xsl:with-param name="setIndex" select="true()" />
<xsl:with-param name="cellNodes" select="$cellNodes[position() != 1]" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<!-- Fastest cell repetition by creating cell once and copying, works not for
a) cells with formula (need of actual cell postition)
b) cells, which start with ss:Index (as ss:Index is not allowed to be repeated) -->
<xsl:when test="not(@table:formula) and not($setIndex)">
<!-- In case a non-empty cell is being repeated, the cell will be created
in a variabel, which is as many times given out, as being repeated -->
<xsl:variable name="tableCell">
<xsl:call-template name="create-table-cell">
<xsl:with-param name="setIndex" select="false()" /><!-- copied cells may not have indices -->
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:call-template>
</xsl:variable>
<xsl:call-template name="repeat-copy-table-cell">
<xsl:with-param name="tableCell" select="$tableCell" />
<xsl:with-param name="repetition" select="$repetition" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:call-template>
<xsl:apply-templates select="$cellNodes[2]">
<xsl:with-param name="calculatedCellPosition" select="$nextMatchedCellPosition" />
<xsl:with-param name="calculatedRowPosition" select="$calculatedRowPosition" />
<xsl:with-param name="cellNodes" select="$cellNodes[position() != 1]" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:apply-templates>
</xsl:when>
<!-- explicit writing (instead of copying) of cell for the cases mentioned above -->
<xsl:otherwise>
<xsl:call-template name="create-table-cell">
<xsl:with-param name="setIndex" select="$setIndex" /><!-- a possible Index will be created -->
<xsl:with-param name="calculatedCellPosition" select="$repetitionCellPosition" />
<xsl:with-param name="calculatedRowPosition" select="$calculatedRowPosition" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:call-template>
<xsl:choose>
<!-- as long there is a repetition (higher '1') stay on the same cell node -->
<xsl:when test="$repetition &gt; 1">
<xsl:call-template name="table:table-cell">
<xsl:with-param name="calculatedCellPosition" select="$nextMatchedCellPosition" />
<xsl:with-param name="calculatedRowPosition" select="$calculatedRowPosition" />
<xsl:with-param name="repetitionCellPosition">
<xsl:choose>
<xsl:when test="@table:number-columns-spanned">
<xsl:value-of select="$repetitionCellPosition + @table:number-columns-spanned" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$repetitionCellPosition + 1"/>
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
<xsl:with-param name="nextMatchedCellPosition" select="$nextMatchedCellPosition" />
<xsl:with-param name="repetition" select="$repetition - 1" />
<xsl:with-param name="cellNodes" select="$cellNodes" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="$cellNodes[2]">
<xsl:with-param name="calculatedCellPosition" select="$nextMatchedCellPosition" />
<xsl:with-param name="calculatedRowPosition" select="$calculatedRowPosition" />
<xsl:with-param name="cellNodes" select="$cellNodes[position() != 1]" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<!-- in case no repetition took place -->
<xsl:choose>
<!-- neglect en empty cells by using ss:Index Attribut -->
<xsl:when test="not(text()) and not(*) and not(@*)">
<xsl:choose>
<!-- if it is the last cell, write this cell -->
<xsl:when test="count($cellNodes) = 1">
<xsl:call-template name="create-table-cell">
<xsl:with-param name="setIndex" select="true()" />
<xsl:with-param name="calculatedCellPosition" select="$nextMatchedCellPosition - 1" />
<xsl:with-param name="calculatedRowPosition" select="$calculatedRowPosition" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="$cellNodes[2]">
<xsl:with-param name="setIndex" select="true()" />
<xsl:with-param name="calculatedCellPosition" select="$nextMatchedCellPosition" />
<xsl:with-param name="calculatedRowPosition" select="$calculatedRowPosition" />
<xsl:with-param name="cellNodes" select="$cellNodes[position() != 1]" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<!-- create cell and use/unset the ss:Index -->
<xsl:call-template name="create-table-cell">
<xsl:with-param name="setIndex" select="$setIndex" />
<xsl:with-param name="calculatedCellPosition" select="$calculatedCellPosition" />
<xsl:with-param name="calculatedRowPosition" select="$calculatedRowPosition" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:call-template>
<xsl:apply-templates select="$cellNodes[2]">
<xsl:with-param name="calculatedCellPosition" select="$nextMatchedCellPosition" />
<xsl:with-param name="calculatedRowPosition" select="$calculatedRowPosition" />
<xsl:with-param name="cellNodes" select="$cellNodes[position() != 1]" />
<xsl:with-param name="columnNodes" select="$columnNodes" />
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Copies the variable 'tableCell' to the output as often as 'repetition' -->
<xsl:template name="repeat-copy-table-cell">
<xsl:param name="tableCell" />
<xsl:param name="repetition" />
<xsl:if test="$repetition &gt; 0">
<xsl:copy-of select="$tableCell"/>
<xsl:call-template name="repeat-copy-table-cell">
<xsl:with-param name="tableCell" select="$tableCell" />
<xsl:with-param name="repetition" select="$repetition - 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="create-table-cell">
<xsl:param name="setIndex" select="false()" />
<xsl:param name="calculatedCellPosition" />
<xsl:param name="calculatedRowPosition" />
<xsl:param name="columnNodes" />
<xsl:element name="Cell" namespace="urn:schemas-microsoft-com:office:spreadsheet">
<xsl:if test="$setIndex">
<xsl:attribute name="ss:Index">
<xsl:value-of select="$calculatedCellPosition"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="@table:number-columns-spanned &gt; 1">
<xsl:attribute name="ss:MergeAcross">
<xsl:value-of select="@table:number-columns-spanned - 1" />
</xsl:attribute>
</xsl:if>
<xsl:if test="@table:number-rows-spanned &gt; 1">
<xsl:attribute name="ss:MergeDown">
<xsl:value-of select="@table:number-rows-spanned - 1" />
</xsl:attribute>
</xsl:if>
<xsl:variable name="link" select="descendant::text:a/@xlink:href" />
<xsl:if test="$link">
<xsl:attribute name="ss:HRef">
<xsl:value-of select="$link" />
</xsl:attribute>
</xsl:if>
<xsl:choose>
<xsl:when test="@table:style-name">
<xsl:apply-templates select="@table:style-name" />
</xsl:when>
<xsl:otherwise>
<xsl:if test="$firstDefaultCellStyle != ''">
<xsl:variable name="defaultCellStyle" select="$columnNodes/table:table-column[position() = $calculatedCellPosition]/@table:default-cell-style-name" />
<xsl:if test="$defaultCellStyle">
<xsl:if test="not($defaultCellStyle = 'Default')">
<xsl:attribute name="ss:StyleID"><xsl:value-of select="$defaultCellStyle"/></xsl:attribute>
</xsl:if>
</xsl:if>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
<xsl:apply-templates select="@table:formula">
<xsl:with-param name="calculatedCellPosition" select="$calculatedCellPosition" />
<xsl:with-param name="calculatedRowPosition" select="$calculatedRowPosition" />
</xsl:apply-templates>
<xsl:choose>
<xsl:when test="*">
<!-- in case it is not an empty cell
As the sequence of comment and data is opposite in Excel and Calc no match work here, in both comments exist only once
Possible Table Content of interest: text:h|text:p|text:list -->
<xsl:if test="text:h | text:p | text:list">
<xsl:variable name="valueType">
<xsl:choose>
<xsl:when test="@office:value-type">
<xsl:value-of select="@office:value-type" />
</xsl:when>
<xsl:otherwise>string</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:call-template name="ss:Data">
<xsl:with-param name="valueType" select="$valueType" />
<xsl:with-param name="cellStyleName" select="@table:style-name" />
</xsl:call-template>
</xsl:if>
<xsl:if test="office:annotation">
<xsl:element name="Comment">
<xsl:if test="office:annotation/@office:author">
<xsl:attribute name="ss:Author"><xsl:value-of select="office:annotation/@office:author" /></xsl:attribute>
</xsl:if>
<xsl:if test="office:annotation/@office:display = 'true'">
<xsl:attribute name="ss:ShowAlways">1</xsl:attribute>
</xsl:if>
<!-- ss:Data is oblicatory, but not the same as the ss:Cell ss:Data child, as it has no attributes -->
<ss:Data xmlns="http://www.w3.org/TR/REC-html40">
<xsl:for-each select="office:annotation/text:p">
<xsl:choose>
<xsl:when test="*">
<!-- paragraph style have to be neglected due to Excel error,
which does not allow shadowing their HTML attributes -->
<xsl:for-each select="*">
<xsl:call-template name="style-and-contents" />
</xsl:for-each>
</xsl:when>
<xsl:when test="@text:style-name">
<xsl:call-template name="style-and-contents" />
</xsl:when>
<xsl:otherwise>
<!-- if no style is set, BOLD is set as default -->
<B>
<xsl:call-template name="style-and-contents" />
</B>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</ss:Data>
</xsl:element>
</xsl:if>
</xsl:when>
</xsl:choose>
</xsl:element>
</xsl:template>
<!-- comments are handled separately in the cell -->
<xsl:template match="office:annotation" />
<xsl:template match="dc:date" />
<xsl:template name="ss:Data">
<!-- the default value is 'String' in the office -->
<xsl:param name="valueType" select="'string'" />
<xsl:param name="cellStyleName" />
<xsl:choose>
<xsl:when test="descendant::*/@text:style-name">
<xsl:choose>
<xsl:when test="$valueType = 'string'">
<ss:Data ss:Type="String" xmlns="http://www.w3.org/TR/REC-html40">
<xsl:apply-templates>
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:apply-templates>
</ss:Data>
</xsl:when>
<xsl:when test="$valueType = 'boolean'">
<ss:Data ss:Type="Boolean" xmlns="http://www.w3.org/TR/REC-html40">
<xsl:apply-templates>
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:apply-templates>
</ss:Data>
</xsl:when>
<xsl:when test="$valueType = 'date'">
<ss:Data ss:Type="DateTime" xmlns="http://www.w3.org/TR/REC-html40">
<xsl:apply-templates>
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:apply-templates>
</ss:Data>
</xsl:when>
<!-- float, time, percentage, currency (no 'Error' setting) -->
<xsl:otherwise>
<ss:Data ss:Type="Number" xmlns="http://www.w3.org/TR/REC-html40">
<xsl:apply-templates>
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:apply-templates>
</ss:Data>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:element name="Data">
<xsl:call-template name="ss:Type">
<xsl:with-param name="valueType" select="$valueType" />
</xsl:call-template>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="ss:Type">
<xsl:param name="valueType" select="'string'" />
<xsl:choose>
<xsl:when test="$valueType = 'string'">
<xsl:attribute name="ss:Type">String</xsl:attribute>
<xsl:apply-templates select="*"/>
</xsl:when>
<xsl:when test="$valueType = 'boolean'">
<xsl:attribute name="ss:Type">Boolean</xsl:attribute>
<xsl:choose>
<xsl:when test="@office:boolean-value = 'true'">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="$valueType = 'date' or $valueType = 'time'">
<!-- issue in Excel: can not have an empty 'DateTime' cell -->
<xsl:attribute name="ss:Type">DateTime</xsl:attribute>
<!-- Gathering information of two StarOffice date/time attributes
Excel always needs both informations in one attribute -->
<xsl:choose>
<xsl:when test="@office:date-value">
<!-- office:date-value may contain time (after 'T')-->
<xsl:choose>
<xsl:when test="contains(@office:date-value, 'T')">
<!-- in case time is also part of the date -->
<xsl:value-of select="substring-before(@office:date-value, 'T')" />
<xsl:text>T</xsl:text>
<xsl:value-of select="substring-after(@office:date-value,'T')" />
<xsl:if test="not(contains(@office:date-value,'.'))">
<xsl:text>.</xsl:text>
</xsl:if>
<xsl:text>000</xsl:text>
</xsl:when>
<xsl:when test="@office:time-value">
<!-- conatains date and time (time will be evaluated later -->
<xsl:value-of select="@office:date-value" />
<xsl:text>T</xsl:text>
<xsl:choose>
<xsl:when test="@table:formula or contains(@office:time-value,',')">
<!-- customized number types not implemented yet -->
<xsl:text>00:00:00.000</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="translate(substring-after(@office:time-value,'PT'),'HMS','::.')" />
<xsl:if test="not(contains(@office:time-value,'S'))">
<xsl:text>.</xsl:text>
</xsl:if>
<xsl:text>000</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@office:date-value" />
<xsl:text>T00:00:00.000</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:if test="@office:time-value">
<xsl:text>1899-12-31T</xsl:text>
<xsl:choose>
<xsl:when test="@table:formula or contains(@office:time-value,',')">
<!-- customized number types not implemented yet -->
<xsl:text>00:00:00.000</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="translate(substring-after(@office:time-value,'PT'),'HMS','::.')" />
<xsl:if test="not(contains(@office:time-value,'S'))">
<xsl:text>.</xsl:text>
</xsl:if>
<xsl:text>000</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<!-- float, percentage, currency (no 'Error' setting) -->
<xsl:otherwise>
<xsl:attribute name="ss:Type">Number</xsl:attribute>
<xsl:value-of select="@office:value" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- ******************** -->
<!-- *** Common Rules *** -->
<!-- ******************** -->
<xsl:template match="*">
<xsl:param name="cellStyleName" />
<!-- LineBreak in Cell -->
<xsl:if test="preceding-sibling::text:p[1]"><xsl:text>&#10;</xsl:text></xsl:if>
<xsl:call-template name="style-and-contents">
<xsl:with-param name="cellStyleName" select="$cellStyleName" />
</xsl:call-template>
</xsl:template>
<!-- disabling draw:frames -->
<xsl:template match="draw:frame" />
<xsl:template match="text:s">
<xsl:call-template name="write-breakable-whitespace">
<xsl:with-param name="whitespaces" select="@text:c" />
</xsl:call-template>
</xsl:template>
<!--write the number of 'whitespaces' -->
<xsl:template name="write-breakable-whitespace">
<xsl:param name="whitespaces" />
<xsl:text> </xsl:text>
<xsl:if test="$whitespaces >= 1">
<xsl:call-template name="write-breakable-whitespace">
<xsl:with-param name="whitespaces" select="$whitespaces - 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
<!-- allowing all matched text nodes -->
<xsl:template match="text()"><xsl:value-of select="." /></xsl:template>
</xsl:stylesheet>