2

申し訳ありませんが、私は XSL を学んでおり、次のようなテーブルを表示したいと考えています。

| | パラメータ 1 | パラメータ 2 |
-------+------+---------
| | p1.1 | p1.2 | p2 |
-------+------+---------
| | a11 | a21 | b01 |
| | a12 | a22 | b02 |

今、私はxmlを持っています:

 <?xml version="1.0" encoding="UTF-8"?>
 <tb>
    <col title="Param1">
        <row name="1">
        <stats name="p1.1" >a11</stats>
        <stats name="p1.2" >a12</stats>
        </row>
        <row name="2">
        <stats name="p1.1" >a21</stats>
        <stats name="p1.2" >a22</stats>
        </row>
    </col>
    <col title="Param2">
        <row name="1">
        <stats name="p2" >b01</stats>
        </row>
        <row name="2">
        <stats name="p2" >b02</stats>
        </row>
    </col>

および xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:for-each select="tb">
    <table class="data_table" style="width: 100%; background:gray">
        <thead>
          <tr>
         <xsl:for-each select="col">
            <xsl:choose>
            <xsl:when test="count(row[1]/stats) > 1">
                <th colspan="{count(row[1]/stats)}">
                    <xsl:value-of select="@title" />
                </th>
            </xsl:when>
            <xsl:otherwise>
                <th><xsl:value-of select="@title" /></th>
            </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
    </tr>
    <tr>
        <xsl:for-each select="col/row[1]/stats">
            <th><xsl:value-of select="@name" /></th>
        </xsl:for-each>
    </tr>
        </thead>
        <tbody>

           <tr>
                <xsl:for-each select="col/row[1]/stats">
                <td>
                    <xsl:value-of select="." />
                </td>
                </xsl:for-each>
              </tr>
              <tr>
                <xsl:for-each select="col/row[2]/stats">
                <td>
                <xsl:value-of select="." />
            </td>
                    </xsl:for-each>
          </tr>
        </tbody>
      </table>
   </xsl:for-each>

動作しますが、単一の FOR を使用してテーブルの行を組み立てるこのコードを改善するにはどうすればよいですか? この例では、2 行 (a11|a21|b01 と a12|a22|b02) と 3 列しかありませんが、これは変更される可能性があります (20 行、4 列...)。同じ行に属するセルをグループ化する必要があるかもしれません。

4

1 に答える 1

4

XSLT を改善するために最初に行うことは、テンプレートを使用することです。それが完了したら、次のようにして、任意の数の行を処理できるようにします。

<col>このソリューションは、ソース データのすべてに、<row>必要なすべての行があることを前提としています。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/tb">
    <table class="data_table" style="width: 100%; background:gray">
      <thead>
        <tr>
          <xsl:apply-templates select="col" mode="titles" />
        </tr>
        <tr>
          <xsl:apply-templates select="col/row[1]/stats" mode="titles" />
        </tr>
      </thead>
      <tbody>
        <xsl:apply-templates select="col[1]/row" />
      </tbody>
    </table>

  </xsl:template>

  <xsl:template match="col" mode="titles">
    <th>
      <xsl:apply-templates select="(.)[row[1]/stats[2]]" mode="colSpan" />
      <xsl:value-of select="@title"/>
    </th>
  </xsl:template>

  <xsl:template match="col" mode="colSpan">
    <xsl:attribute name="colspan">
      <xsl:value-of select="count(row[1]/stats)"/>
    </xsl:attribute>
  </xsl:template>

  <xsl:template match="stats" mode="titles">
    <th>
      <xsl:value-of select="@name" />
    </th>
  </xsl:template>

  <xsl:template match="row">
    <tr>
      <xsl:apply-templates select="../../col/row[@name = current()/@name]/stats" /> 
    </tr>
  </xsl:template>

  <xsl:template match="stats">
    <td>
      <xsl:value-of select="." />
    </td>
  </xsl:template>
</xsl:stylesheet>

サンプル入力で実行すると、結果は次のようになります。

<table class="data_table" style="width: 100%; background:gray">
  <thead>
    <tr>
      <th colspan="2">Param1</th>
      <th>Param2</th>
    </tr>
    <tr>
      <th>p1.1</th>
      <th>p1.2</th>
      <th>p2</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>a11</td>
      <td>a12</td>
      <td>b01</td>
    </tr>
    <tr>
      <td>a21</td>
      <td>a22</td>
      <td>b02</td>
    </tr>
  </tbody>
</table>
于 2013-07-23T09:33:02.030 に答える