XSLT创建具有动态行数和列数的表

时间:2015-09-23 18:22:16

标签: xml xslt

我是XSLT的新手,需要你的帮助。我必须在XSLT中创建单词表。列数和行数是动态的。

这是一个示例XML:

<Movies>
  <Genre name="Action">
    <Movie>
      <Name>Crash</Name>
      <Released>2005</Released>
    </Movie>
  </Genre>
  <Genre name="Drama">
    <Movie>
      <Name>The Departed</Name>
      <Released>2006</Released>
    </Movie>
    <Movie>
      <Name>The Pursuit of Happyness</Name>
      <Released>2006</Released>
    </Movie>
  </Genre>
  <Genre name="Comedy">
    <Movie>
      <Name>The Bucket List</Name>
      <Released>2007</Released>
    </Movie>
  </Genre>
</Movies>

genre元素可以包含任意数量的电影元素。

表格应如下所示:
Picture

这是XSLT:

    <xsl:template match="/">
        <w:document>
            <w:body>    
                <w:tbl>
                    <w:tr>
                        <xsl:for-each select="/Movies/Genre">
                            <w:tc>
                                <w:p>
                                    <w:r>
                                        <w:t>
                                            <xsl:value-of select="@name"/>
                                        </w:t>
                                    </w:r>
                                </w:p>
                            </w:tc>
                        </xsl:for-each> 
                    </w:tr>

                    <!-- Movies? -->

                </w:tbl>
            </w:body>
        </w:document>
    </xsl:template>

列标题不是问题,但如何根据需要编写电影元素?有两种 for-each 循环的方法,还是我必须使用 apply-templates ?感谢您的支持!

1 个答案:

答案 0 :(得分:1)

不幸的是我不熟悉DOCX格式,因此您可能想要更正输出,但对于XSLT,以下应该可以解决问题

  <xsl:template match="/">
    <w:document>
      <w:body>
        <w:tbl>
          <w:tr>
            <xsl:for-each select="/Movies/Genre">
              <w:tc>
                <w:p>
                  <w:r>
                    <w:t>
                      <xsl:value-of select="@name"/>
                    </w:t>
                  </w:r>
                </w:p>
              </w:tc>
            </xsl:for-each>
          </w:tr>

          <!-- Movies? -->

          <xsl:call-template name="movies-row">
            <xsl:with-param name="i" select="1"></xsl:with-param>
          </xsl:call-template>

        </w:tbl>
      </w:body>
    </w:document>
  </xsl:template>

  <xsl:template name="movies-row">
    <xsl:param name="i"/>

      <w:tr>
        <xsl:for-each select="/Movies/Genre">
          <w:tc>
            <w:p>
              <w:r>
                <w:t>
                  <xsl:choose>
                    <xsl:when test="count(Movie) >= $i">
                      <xsl:value-of select="concat(Movie[$i]/Name, ' (', Movie[$i]/Released, ')')"/>
                    </xsl:when>
                    <xsl:otherwise>
                      <!-- empty cell -->
                    </xsl:otherwise>
                  </xsl:choose>
                </w:t>
              </w:r>
            </w:p>
          </w:tc>
        </xsl:for-each>
      </w:tr>

    <xsl:if test="/Movies/Genre[count(Movie) > $i]">
      <xsl:call-template name="movies-row">
        <xsl:with-param name="i" select="$i + 1"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>