2

我有以下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>

我想创建以下结果:

在此处输入图像描述

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

但这会产生这样的表格:

在此处输入图像描述

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

4

3 回答 3

4

这个怎么样:

<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()来查看您是否是第一个Allelethis Locus,并last()给出Allele当前Locus包含的元素数量。这ancestor::Locus[1]是因为我们需要Locus在当前上下文是它的第一个点处提取 Id Allele

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

        <xsl:if test="position() = 1">
          <td>
            <xsl:if test="last() &gt; 1">
              <xsl:attribute name="rowspan">
                <xsl:value-of select="last()" />
              </xsl:attribute>
            </xsl:if>
            <xsl:value-of select="ancestor::Locus[1]/Id"/>
          </td>
        </xsl:if>
于 2013-10-30T13:59:32.107 回答
3

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

<xsl:variable name="recordCount" select="count(Alleles/Allele)"/>
<td rowspan="{$recordCount}"><xsl:value-of select="Id"/></td>
于 2013-10-30T14:03:05.417 回答
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>
于 2013-10-30T14:03:42.167 回答