xml - XSLT 1.0 - 使用基于单独 XML 元素的两个表构建 XML 电子表格
问题描述
我需要从包含以单独元素结构化的数据的 XML 文档(使用 XSLT 1.0)以某种格式构建 XML 电子表格 (SpreadsheetML) 文件。一个简化的示例如下:
<Root>
<DetailsTable>
<row data="1"/>
<row data="2"/>
<row data="3"/>
<row data="4"/>
<row data="5"/>
<row data="6"/>
<row data="7"/>
<row data="8"/>
<row data="9"/>
<row data="10"/>
<row data="11"/>
<row data="12"/>
<row data="13"/>
<row data="14"/>
</DetailsTable>
<SummaryTable>
<row data="A"/>
<row data="B"/>
<row data="C"/>
</SummaryTable>
</Root>
所需的输出应该在 Excel 工作表上布置为两个单独的“表格”,其中一个位于另一个的中间 - 如屏幕截图所示:
问题是,通过 XSLT 转换,我需要逐一打印行,并且必须在打印行时打印所有单元格 - 因此,对于某些行(例如索引 4、5、6、7),我需要添加一些特殊的单元格,我将从SummaryTable
XML 元素中获取它们的值。
换句话说,输出 XML 格式是这样的:
<Table>
<Row>
<Cell><Data >DetailsTable</Data></Cell>
</Row>
<Row>
<Cell><Data >1</Data></Cell>
</Row>
<Row>
<Cell><Data >2</Data></Cell>
</Row>
<Row>
<Cell><Data >3</Data></Cell>
<Cell><Data >SummaryTable</Data></Cell>
</Row>
<Row>
<Cell><Data >4</Data></Cell>
<Cell><Data >A</Data></Cell>
</Row>
<Row>
<Cell><Data >5</Data></Cell>
<Cell><Data >B</Data></Cell>
</Row>
<Row>
<Cell><Data >6</Data></Cell>
<Cell><Data >C</Data></Cell>
</Row>
<Row>
<Cell><Data >7</Data></Cell>
</Row>
<Row>
<Cell><Data >8</Data></Cell>
</Row>
<Row>
</Table>
问题是我无法控制详细信息表中的行数 - 只需对它们执行 'for-each' 并使用position()
.
然而,可能是太少(例如只有一个行元素),在这种情况下for-each
永远不会迭代到索引 4、5、6、7,所以我的汇总表不会被打印 - 这种情况下的预期输出应该是:
我正在考虑执行 for-each 循环指定次数(例如 7 次),以便我打印出前七行以及汇总表,然后for-each
在元素上再次执行循环DetailsTable/row
,但跳过前 7 个索引位置,但这似乎是一个令人讨厌的解决方法。
还有其他想法吗?
解决方案
一种解决方案,虽然看起来不是很优雅,但是有一个递归模板,它递增一个行号,直到它到达详细行或摘要行的末尾,这取决于哪个更大。
试试这个 XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="firstSummaryRow" select="4" />
<xsl:variable name="lastDetailRow" select="1 + count(/*/DetailsTable/row)" />
<xsl:variable name="lastSummaryRow" select="$firstSummaryRow + count(/*/SummaryTable/row)" />
<xsl:template match="/*">
<xsl:call-template name="Rows" />
</xsl:template>
<xsl:template name="Rows">
<xsl:param name="rowNumber" select="1" />
<Row>
<Cell>
<Data>
<xsl:choose>
<xsl:when test="$rowNumber = 1">Details Table</xsl:when>
<xsl:otherwise>
<xsl:value-of select="DetailsTable/row[position() = $rowNumber - 1]/@data" />
</xsl:otherwise>
</xsl:choose>
</Data>
</Cell>
<xsl:if test="$rowNumber >= $firstSummaryRow and $rowNumber <= $lastSummaryRow">
<Cell Index="3">
<Data>
<xsl:choose>
<xsl:when test="$rowNumber = $firstSummaryRow">Summary Table</xsl:when>
<xsl:otherwise>
<xsl:value-of select="SummaryTable/row[position() = $rowNumber - $firstSummaryRow]/@data" />
</xsl:otherwise>
</xsl:choose>
</Data>
</Cell>
</xsl:if>
</Row>
<xsl:if test="$rowNumber < $lastDetailRow or $rowNumber < $lastSummaryRow">
<xsl:call-template name="Rows">
<xsl:with-param name="rowNumber" select="$rowNumber + 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
推荐阅读
- javascript - 如何在尝试使用 innerHTML 时修复按钮禁用问题?
- c++ - 如何在 vs code c++ 中添加静态库?
- matlab - 导入某些值的数据时,Matlab“失去”“幂”值
- javascript - 让机器人对其上方的消息做出反应
- angular - 如何处理 tiff 图像,以便可以在 chrome 中显示角度?
- ios - 为未知枚举返回相同的原始值
- python - 混合日期时间格式需要是一种格式
- c# - SignInManager.IsSignedIn(User) 方法总是返回 false
- javascript - 无法读取从documents.getElementsByName获取的NodeList的字段
- python - 你知道为什么 Django ls 可能不会出现在项目目录中吗?