我如何获取这个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 &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>

根据您的输入,它会产生:
<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),我将进一步研究优化我的版本。

09-10 05:59
查看更多