如何使用XSLT动态获取行的值

时间:2009-09-09 06:31:22

标签: xml xslt

我必须使用XSLT和CSS创建一个表。该表应如下所示:

ID    FNAME
1    AA
2    BB

我的XML是:

<students>
  <studentDetails>
    <id>1</id>
    <fname>AA</fname>
  </studentDetails>
  <studentDetails>
    <id>2</id>
    <fname>BB</fname>
  </studentDetails>
<students>

到目前为止我的XSLT:

<xsl:template match="students">
  <div>
    <div class="idcol">
      <div class="header">
        <xsl:text>ID</xsl:text>
      </div>
      <div class="row">
        <xsl:value-of select="studentDetails[1]/id"/>
      </div>
      <div class="row">
        <xsl:value-of select="studentDetails[2]/id"/>
      </div>
    </div>
    <div class="fnamecol">
      <div class="header">
        <xsl:text>FNAME</xsl:text>
      </div>
      <div class="row">
        <xsl:value-of select="studentDetails[1]/fname"/>
      </div>
      <div class="row">
        <xsl:value-of select="studentDetails[2]/fname"/>
      </div>
    </div>
  </div>
</xsl:template>

应用CSS后,输出看起来正确,但问题是我直接使用了[1][2]。所以,如果有第3行,那么我必须再次更改我的代码。如何使用某个索引动态地执行此操作 - 有人可以帮忙吗?

3 个答案:

答案 0 :(得分:2)

你可以使用<xsl:for-each>,但我认为这更简洁,可以扩展到任意多列(只要它们都是一样的):

<xsl:stylesheet version="1.0" xmlns:xs="...">

  <xsl:template match="students">
    <div>
      <div class="idcol">
        <div class="header">
          <xsl:text>ID</xsl:text>
        </div>
        <xsl:apply-templates>
          <xsl:with-param name="child-name" select="'id'"/>
        </xsl:apply-templates>
      </div>
      <div class="fnamecol">
        <div class="header">
          <xsl:text>FNAME</xsl:text>
        </div>
        <xsl:apply-templates>
          <xsl:with-param name="child-name" select="'fname'"/>
        </xsl:apply-templates>
      </div>
    </div>
  </xsl:template>

  <xsl:template match="studentDetails">
    <xsl:param name="child-name"/>
    <div class="row">
      <xsl:value-of select="*[name() = $child-name]"/>
    </div>
  </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:2)

更动态的解决方案(动态行列):

<xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>    
  <xsl:output method="xml" indent="yes" encoding="utf-8" />

  <xsl:variable name="l" select="'abcdefghijklmnopqrstuvwxyz'" />
  <xsl:variable name="u" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
  <xsl:key name="kSd" match="studentDetails/*" use="name()" />

  <xsl:template match="students">
    <div>
      <xsl:for-each select="studentDetails[1]/*">
        <div class="{name()}col">
          <div class="header">
            <xsl:value-of select="translate(name(), $l, $u)" />
          </div>
          <xsl:apply-templates select="key('kSd', name())" />
        </div>           
      </xsl:for-each>
    </div>
  </xsl:template>

  <xsl:template match="studentDetails/*">
    <div class="row">
      <xsl:value-of select="." />
    </div>
  </xsl:template>

</xsl:stylesheet>

产生

<div>
  <div class="idcol">
    <div class="header">ID</div>
    <div class="row">1</div>
    <div class="row">2</div>
  </div>
  <div class="fnamecol">
    <div class="header">FNAME</div>
    <div class="row">AA</div>
    <div class="row">BB</div>
  </div>
</div>

答案 2 :(得分:0)

首先,您应重新组织HTML代码以将每一行表示为一行。如果按列组织表,则从源XML数据创建该代码并不容易。

重新组织HTML后,您可以为节点“studentDetails”编写新模板。将每行的代码移动到该模板中。在匹配节点“student”的模板中插入

<xsl:apply-templates match="studentDetails" />

为每位学生插入信息。