通过XSL添加rowspan

时间:2013-10-30 13:52:59

标签: xslt

我有以下xml:

<?xml version="1.0" encoding="ISO-8859-1"?>

<Loci>
    <Locus>
        <Id>MTBC1726</Id>
        <Alleles>
            <Allele>
                <Name>1.0</Name>
                <Description>No annotation provided</Description>
            </Allele>
            <Allele>
                <Name>2.0</Name>
                <Description>No annotation provided</Description>
            </Allele>
        </Alleles>
    </Locus>
    <Locus>
        <Id>MTBC3142</Id>
        <Alleles>
            <Allele>
                <Name>1.0</Name>
                <Description>No annotation provided</Description>
            </Allele>
        </Alleles>
    </Locus>
</Loci>

我想创建以下结果:

enter image description here

,在HTML中,看起来像这样:

<html>
<body>

<table border="1">
  <tr>
    <th>Locus</th>
    <th>Allele</th>
    <th>Description</th>
  </tr>
  <tr>
    <td rowspan="2">MTBC1726</td>
    <td>1.0</td>
    <td >No annotation provided</td>
  </tr>
  <tr>
    <td>2.0</td>
    <td >No annotation provided</td>
  </tr>
  <tr>
    <td >MTBC3142</td>
    <td>1.0</td>
    <td >No annotation provided</td>
  </tr>
</table>

</body>
</html>

我创建了以下XSL:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <html>
  <body>
    <table border="1">
      <tr>
        <th>Locus</th>
        <th>Allele</th>
        <th>Description</th>
      </tr>
      <xsl:for-each select="Loci/Locus">
      <tr>
        <td><xsl:value-of select="Id"/></td>
        <xsl:for-each select="Alleles/Allele">
          <td><xsl:value-of select="Name"/></td>
          <td><xsl:value-of select="Description"/></td>
        </xsl:for-each>
      </tr>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

但是会生成如下表格:

enter image description here

所以,我的问题是:如何根据rowspan个节点的数量添加<Allele>属性?

3 个答案:

答案 0 :(得分:3)

这个怎么样:

<table border="1">
  <tr>
    <th>Locus</th>
    <th>Allele</th>
    <th>Description</th>
  </tr>
  <xsl:for-each select="Loci/Locus">
    <xsl:for-each select="Alleles/Allele">
      <tr>
        <xsl:if test="position() = 1">
          <td rowspan="{last()}">
            <xsl:value-of select="ancestor::Locus[1]/Id"/>
          </td>
        </xsl:if>
        <td><xsl:value-of select="Name"/></td>
        <td><xsl:value-of select="Description"/></td>
      </tr>
    </xsl:for-each>
  </xsl:for-each>
</table>

这里的想法是,在内部for-each内,您可以使用position()来查看您是否在第一个Allele Locus和{{1}提供当前last()包含的Allele元素的数量。 Locus是因为我们需要在当前上下文为其ancestor::Locus[1]的位置提取Locus Id。

如果您想避免为单等位基因位点添加Allele,则必须使用条件rowspan="1"而不是属性值模板:

xsl:attribute

答案 1 :(得分:3)

您可以使用XSL count()函数定义变量,然后将该变量作为属性值输出:

<xsl:variable name="recordCount" select="count(Alleles/Allele)"/>
<td rowspan="{$recordCount}"><xsl:value-of select="Id"/></td>

答案 2 :(得分:1)

您可以计算Allele的数量并使用该值来创建您的行数。我还进行了检查,以便在只有rowspan=1

的情况下不添加Allele
<xsl:template match="/">
  <html>
  <body>
    <table border="1">
      <tr>
        <th>Locus</th>
        <th>Allele</th>
        <th>Description</th>
      </tr>
      <xsl:for-each select="Loci/Locus">
      <tr>
        <td>
          <xsl:if test="count(Alleles/Allele) &gt; 1">
            <xsl:attribute name="rowspan">
              <xsl:value-of select="count(Alleles/Allele)"/>
            </xsl:attribute>
          </xsl:if>
          <xsl:value-of select="Id"/>
        </td>
        <xsl:for-each select="Alleles/Allele">
          <td><xsl:value-of select="Name"/></td>
          <td><xsl:value-of select="Description"/></td>
        </xsl:for-each>
      </tr>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>