xslt:如何使用 xslt 创建具有多列和多行的表? [英] xslt: How could I use xslt to create a table with multiple columns and rows?

查看:23
本文介绍了xslt:如何使用 xslt 创建具有多列和多行的表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将如何使用此 xml 并为每个部分"元素创建一个包含一列的表格,然后使用 xslt 显示该列中的所有文档"元素?

How would I take this xml and create a table with a column for each "section" element and then display all the "document" elements in that column using xslt?

<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>

谢谢,铝

推荐答案

这是一种可能的解决方案:

This is one possible solution:

<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 &lt; $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 &lt; $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) &gt; $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>

根据您的输入,它会产生:

With your input it produces:

<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>

一般的方法是这样的:

  1. 找出我们将要获得多少行(这发生在 <xsl:template match="Section" mode="findmax"> 中,它递归地找到具有最大值的部分 节点数
  2. 找出我们将获得多少列(通过计算
    的数量)
  3. 调用创建<tr>的模板,并不断调用自己,直到创建了所有必要的行
  4. 在这个模板中,调用了第二个模板,这个模板创建了 s.它不断调用自己,直到达到最大列数(从第 2 步开始)
  1. Find out how many rows we are going to get (this happens in <xsl:template match="Section" mode="findmax">, which recursively finds the section with the maximum number of <Document> nodes
  2. Find out how many columns we are going to get (by counting the number of <Section>s)
  3. calling a templates that creates a <tr>, and keeps calling itself until all necessary rows have been created
  4. in this template, a second template is called, this one creates the <td>s. It keeps calling itself until it reaches the max number of columns (from step 2)

算法:

  • 使用递增的列号和行号作为索引
  • 使用递归实现一对一索引递增(因为在 XSLT 中实际上无法递增变量)
  • 为文档较少的部分创建正确数量的空单元格

存在更高效的版本(可能使用 <xsl:key>s),我会考虑进一步优化我的版本.

A more efficient version (probably using <xsl:key>s) exists, I'll look into optimizing mine a little more.

这篇关于xslt:如何使用 xslt 创建具有多列和多行的表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆