我如何获取这个xml并为每个“section”元素创建一个包含一列的表,然后使用xslt显示该列中的所有“document”元素?
<Documents>
<Section>
<SectionName>Green</SectionName>
<Document>
<FileName>Tier 1 Schedules</FileName>
</Document>
<Document>
<FileName>Tier 3 Schedules</FileName>
</Document>
<Document>
<FileName>Setback Schedule</FileName>
</Document>
<Document>
<FileName>Tier 2 Governance</FileName>
</Document>
</Section>
<Section>
<SectionName>MRO/Refurb</SectionName>
<Document>
<FileName>Tier 2 Governance</FileName>
</Document>
</Section>
谢谢,
铝
最佳答案
这是一个可能的解决方案:
<xsl:variable name="vCountRows">
<xsl:apply-templates select="Documents/Section[1]" mode="findmax" />
</xsl:variable>
<xsl:variable name="vCountCols" select="count(Documents/Section)" />
<xsl:template match="/Documents">
<table r="{$vCountRows}" s="{$vCountCols}">
<thead>
<xsl:call-template name="create-thead" />
</thead>
<tbody>
<xsl:call-template name="create-tr" />
</tbody>
</table>
</xsl:template>
<xsl:template name="create-thead">
<tr>
<xsl:apply-templates select="Section" />
</tr>
</xsl:template>
<xsl:template match="Section">
<th><xsl:value-of select="SectionName" /></th>
</xsl:template>
<xsl:template name="create-tr">
<xsl:param name="row" select="1" />
<tr>
<xsl:call-template name="create-td">
<xsl:with-param name="row" select="$row" />
</xsl:call-template>
</tr>
<xsl:if test="$row < $vCountRows">
<xsl:call-template name="create-tr">
<xsl:with-param name="row" select="$row + 1" />
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template name="create-td">
<xsl:param name="col" select="1" />
<xsl:param name="row" select="1" />
<td>
<xsl:value-of select="Section[$col]/Document[$row]/FileName" />
</td>
<xsl:if test="$col < $vCountCols">
<xsl:call-template name="create-td">
<xsl:with-param name="col" select="$col + 1" />
<xsl:with-param name="row" select="$row" />
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="Section" mode="findmax">
<xsl:variable name="c" select="count(Document)" />
<xsl:variable name="next" select="following-sibling::Section[count(Document) > $c][1]" />
<xsl:choose>
<xsl:when test="$next">
<xsl:apply-templates select="$next" mode="findmax" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$c" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
根据您的输入,它会产生:
<table>
<thead>
<tr>
<td>Green</td>
<td>MRO/Refurb</td>
</tr>
</thead>
<tbody>
<tr>
<td>Tier 1 Schedules</td>
<td>Tier 2 Governance</td>
</tr>
<tr>
<td>Tier 3 Schedules</td>
<td></td>
</tr>
<tr>
<td>Setback Schedule</td>
<td></td>
</tr>
<tr>
<td>Tier 2 Governance</td>
<td></td>
</tr>
</tbody>
</table>
将军说:
找出我们将得到多少行(这发生在
<xsl:template match="Section" mode="findmax">
中,它递归地查找节点数最大的节找出我们将得到多少列(通过计算
<Document>
s的数量)调用创建
<Section>
的模板,并在创建所有必需的行之前一直调用自身在这个模板中,调用第二个模板,这个模板创建
<tr>
s。它一直调用自己,直到达到最大列数(从步骤2开始)算法:
使用递增的列号和行号作为索引
使用递归实现一个一个的索引增量(因为在xslt中实际上不可能对变量进行增量处理)
为文档较少的节创建正确数量的空单元格
有一个更有效的版本(可能使用
<td>
s),我将进一步研究优化我的版本。