0

使用 Excel 2007 生成的电子表格ML(以及更高版本),xl:Row 和 xl:Cell 元素可能包含 ss:Index 的属性,它提供“跳过”干预完全空白单元格的行或列指定。这使得电子表格ML 中的标记更小,但在尝试根据矩阵中实际存在空白单元格的规则几何形状评估矩阵时不方便。

我在 msxml 中创建了一个 XSLT 1.0 例程,它将例如<xsl:Row><xl:Cell ss:Index="3">dave</xl:Cell></xl:Row>类型传入标记转换为“扩展”形式,如下所示:

<Row>
  <Col/><Col/><Col>dave</Col>
</Row>

请注意,“空白”单元格将转换为空的自闭合标签。这很有帮助,因为进一步的 XSLT 可以假设行和列出现在 Row/Col 结构中的正确序号位置。

然而,这个过程处理起来很复杂,而且有点慢。有没有人通过其他机制解决了“解包” ss:Index 值的挑战?您必须假设传入数据中可能存在“空白单元格”。

我的处理平台是经典的 ASP、在 ASP 内部运行的 Jscript、msxml,并将结果返回给浏览器。然而,任何和所有的观点都是受欢迎的,不受这个平台描述的限制。解包过程理想地发生在服务器上,因为序列化的 XSLT 对结果进行操作。

谢谢 Stackoverflow 的读者!

4

1 回答 1

1

XML 结构不是您希望它在电子表格中的结构。我经历了痛苦来解决(MK在某个时候加入)。你需要的大致是这样的(里面还有一些检查):

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:e="urn:schemas-microsoft-com:office:spreadsheet" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" exclude-result-prefixes="e ss">
        <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
        <xsl:param name="sheetname">Sheet1</xsl:param>
        <xsl:template match="e:Workbook">
            <xsl:element name="importdata">
                <xsl:attribute name="type"><xsl:value-of select="$sheetname"/></xsl:attribute>
                <xsl:apply-templates select="e:Worksheet[@ss:Name=$sheetname]"/>
            </xsl:element>
        </xsl:template>
        <xsl:template match="e:Worksheet">
            <xsl:apply-templates select="e:Table/e:Row"/>
        </xsl:template>
        <xsl:template match="ss:Row">
            <xsl:if test="not(ss:Cell[1]/@ss:Index)">
                <!-- We do NOT process records where the first cell is empty -->
                <xsl:element name="record">
                    <xsl:attribute name="position"><xsl:value-of select="position()-1"/></xsl:attribute>
                    <xsl:apply-templates select="e:Cell"/>
                </xsl:element>
            </xsl:if>
        </xsl:template>
        <xsl:template match="ss:Cell">
            <xsl:variable name="curCol">
                <xsl:choose>
                    <xsl:when test="@ss:Index">
                        <xsl:value-of select="@ss:Index"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:call-template name="cell-index">
                            <xsl:with-param name="idx" select="1"/>
                        </xsl:call-template>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:variable>
            <xsl:element name="field">
                <xsl:attribute name="col"><xsl:value-of select="$curCol"/></xsl:attribute>
                <xsl:attribute name="name"><xsl:value-of select="normalize-space(ancestor::e:Table/e:Row[position()=1]/e:Cell[position()=$curCol])"/></xsl:attribute>
                <xsl:value-of select="ss:Data"/>
            </xsl:element>
        </xsl:template>
        <xsl:template name="cell-index">
            <xsl:param name="idx"/>
            <xsl:if test="$idx &lt;= position()">
                <xsl:choose>
                    <xsl:when test="preceding-sibling::ss:Cell[position()=$idx]/@ss:Index">
                        <xsl:value-of select="preceding-sibling::ss:Cell[position()=$idx]/@ss:Index +$idx"/>
                    </xsl:when>
                    <xsl:when test="$idx = position()">
                        <xsl:value-of select="$idx"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:call-template name="cell-index">
                            <xsl:with-param name="idx" select="$idx+1"/>
                        </xsl:call-template>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:if>
        </xsl:template>
        <!-- We don't process the first row since it has the field names in it -->
        <xsl:template match="ss:Row[position()=1]"/>
    </xsl:stylesheet>

让我们知道怎么回事

于 2014-04-23T07:27:15.440 回答