我刚接触XSLT并且遇到一些麻烦来解决这个问题。
输入来自XML Excel文档,格式为:
<Row>
<Cell><Data ss:Type="String">ToE.3</Data></Cell>
<Cell ss:Index="15"><Data ss:Type="String">Maintain</Data></Cell>
<Cell><Data ss:Type="Number">3</Data></Cell>
<Cell><Data ss:Type="String">Other</Data></Cell>
<Cell ss:Index="131"><Data ss:Type="String">Windows 2003</Data></Cell>
<Cell><Data >Microsoft SQL Server 2005</Data></Cell>
</Row>
..more rows (note the excel sheet has 132 columns)
我需要将其转换为标准文本文件,例如(使用右列)分隔符:
Col1 Col2 Col3 ..To.. Col15 Col16 ..To.. Col131
ToE.3 Maintain 3 Windows 2003
问题是如何使用Index属性插入skipt的空行值。
没有空的索引处理的转换如下:
<xsl:for-each select="Row">
<xsl:for-each select="Cell/Data">
<xsl:value-of select="current()"/>
<xsl:text>\</xsl:text>
</xsl:for-each>
<xsl:text> </xsl:text>
</xsl:for-each>
一些帮助将受到热烈赞赏
答案 0 :(得分:1)
第1步:你需要声明输出格式,即“text”而不是“xml”..
第二步:你需要摆脱额外的空白。使用带有element ='*'的Strip-space,这意味着'all'!
第3步:你需要首先写标题行,即col1,col2等。
因此,使用模板匹配选择XML中第一个元素行。假设所有行具有相同的列数,则需要在第一行中写入“COL + NUMBER”.. column numbers = no of cells
。
步骤4:如果单元格是最后一个,则插入'输入字符'..
步骤5:调用泛型函数
步骤6:解释通用功能:
此函数复制由\
分隔的每个单元格下的数据。仅对于第一行,我们将手动调用它,否则模板匹配将处理它。
以下是代码:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template name="Header" match="Row[not(preceding-sibling::Row)]">
<xsl:for-each select="Cell">
<xsl:value-of select="'Col'"/>
<xsl:value-of select="position()"/>
<xsl:if test="position()!=last()">
<xsl:value-of select="'\'"/>
</xsl:if>
</xsl:for-each>
<xsl:text> </xsl:text>
<xsl:call-template name="CopyData"/>
</xsl:template>
<xsl:template name="CopyData" match="Row">
<xsl:for-each select="Cell">
<xsl:for-each select="Data">
<xsl:apply-templates select="."/>
</xsl:for-each>
<xsl:if test="position()!=last()">
<xsl:value-of select="'\'"/>
</xsl:if>
</xsl:for-each>
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
相应的样本输出:
Col1\Col2\Col3\Col4\Col5\Col6
ToE.3\Maintain\3\Other\Windows 2003\Microsoft SQL Server 2005
ToE.3\Maintain\3\Other\Windows 2003\Microsoft SQL Server 2005
答案 1 :(得分:1)
这很棘手,因为当您看到Excel跳过没有数据出现的列时,会为后续的非空列提供ss:Index属性。你必须自己重建“缺失”的细胞位置。也就是说,如果您希望在示例中保留原始列位置,例如“15”或“131”,则插入空格。
同意上面的InfantProgrammer,但建议您在上面的“CopyData”模板中添加一些逻辑,以(a)确定丢失的单元格的数量,然后(b)调用递归的命名模板将'em'写入输出。
<xsl:template name="WriteBlanks">
<xsl:param name="Count" select="0"/>
<xsl:if test="Count > 0">
<xsl:value-of select="'\'"/>
<xsl:call-template name="WriteBlanks">
<xsl:with-param name="Count" select="$Count - 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
您可以执行类似的操作来生成第一行列标题。
考虑到只需将反斜杠字符作为列分隔符编写的简单性,只需创建一长串字符串就可以实现更简洁的方法,然后XPath substring()
需要尽可能多地删除。{{1}}可以实现。但是,递归模板可能适用于更复杂的输出。