使用Excel 2007生成的电子表格(以及更新版本),xl:Row和xl:Cell元素可能包含ss:Index的属性,它提供行“或列”指定“跳过”干预完全空白的单元格。这使得电子表格中的标记更小,但在尝试根据矩阵中实际存在空白单元格的常规几何图形来评估矩阵时不方便。
我在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的挑战:其他机制的指数值?您必须假设传入数据中可能存在“空白单元格”。
我的处理平台是ASP经典,Jscript在ASP,msxml内部运行,并将结果返回给浏览器。然而,欢迎任何和所有观点,不受此平台描述的约束。解包过程理想地发生在服务器上,因为序列化的XSLT对结果进行操作。
谢谢Stackoverflow读者!
答案 0 :(得分:1)
XML结构不是您希望它在电子表格中的结构。我经历了痛苦到sort it out(在某些时候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 <= 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>
让我们知道它是怎么回事