将xml转换为多列html表

时间:2013-03-15 19:29:09

标签: asp.net xml xslt

我想拥有以下XML:

<?xml version="1.0" standalone="yes"?>
<NewDataSet>
  <categories>
    <name>Badges &amp; Holders</name>
    <value>1000111</value>
  </categories>
  <categories>
    <name>Clips, Tacks &amp; Rubber Bands</name>
    <value>1000113</value>
  </categories>
  <categories>
    <name>Clocks</name>
    <value>1000114</value>
  </categories>
  <categories>
    <name>Indexing Flags &amp; Tabs</name>
    <value>1000115</value>
  </categories>
  <categories>
    <name>Magnification</name>
    <value>1000116</value>
  </categories>
  <categories>
    <name>Pad Holders</name>
    <value>1000117</value>
  </categories>
  <categories>
    <name>Paper Punch Accessories</name>
    <value>1000118</value>
  </categories>
  <categories>
    <name>Paper Punches</name>
    <value>1000119</value>
  </categories>
  <categories>
    <name>Scissors, Rulers &amp; Paper Trimmers</name>
    <value>1000120</value>
  </categories>
  <categories>
    <name>Signs &amp; Nameplates</name>
    <value>1000121</value>
  </categories>
  <categories>
    <name>Stamps &amp; Pads Accessories</name>
    <value>1000122</value>
  </categories>
  <categories>
    <name>Stapler Accessories</name>
    <value>1000123</value>
  </categories>
  <categories>
    <name>Staplers</name>
    <value>1000124</value>
  </categories>
  <categories>
    <name>Tags &amp; Tickets</name>
    <value>1000125</value>
  </categories>
  <categories>
    <name>Tape, Glue &amp; Adhesives</name>
    <value>1000126</value>
  </categories>
</NewDataSet>

然后将其转换为HTML(表格):

<table>
  <tr>
    <td>
      <div>
        <img src="Path/" + {value} + ".jpg"></img>
      </div>
      <div>
        <span onclick="Critia(this, '{value}')">
          <xsl:value-of select="name"/>
        </span>
      </div>
    </td>
  </tr>
</table>

但这是踢球者。我只需要它有5列TD,然后用新的TR重新开始......一路向下。如果它有例如XML中的12个项目,那么我需要它继续进行并且有15个TD(我推测),这样表格就是一个很好的方块。

将来我们将在这个XML中为每个“类别”项目提供一个“PictureURL”或类似的东西,就像名称和值一样。我打赌,如果我现在可以开始工作的话,我可以在以后自己工作。

非常感谢您的帮助!经过几天尝试和谷歌搜索后,XSLT语法让我感到困惑。

以下是我一直在尝试做的工作而无法完成工作:

<table>
  <xsl:for-each select="categories[position() mod 5 = 1]">
    <xsl:variable name="pos" select="position() - 1" />
    <tr>
      <td >
        <xsl:value-of select="."/>
        <span onclick="Critia(this, '{value}')">
          <xsl:value-of select="name[position() = ($pos * 5)]"/>
        </span>
      </td>
      <td>
        <xsl:value-of select="//categories[position() = ($pos * 5) + 2]"/>
        <span onclick="Critia(this, '{value}')">
          <xsl:value-of select="name[position() = ($pos * 5) + 2]"/>
        </span>
      </td>
      <td>
        <xsl:value-of select="//categories[position() = ($pos * 5) + 3]"/>
        <span onclick="Critia(this, '{value}')">
          <xsl:value-of select="name[position() = ($pos * 5) + 3]"/>
        </span>
      </td>
      <td>
        <xsl:value-of select="//categories[position() = ($pos * 5) + 4]"/>
        <span onclick="Critia(this, '{value}')">
          <xsl:value-of select="name[position() = ($pos * 5) + 4]"/>
        </span>
      </td>
      <td>
        <xsl:value-of select="//categories[position() = ($pos * 5) + 5]"/>
        <span onclick="Critia(this, '{value}')">
          <xsl:value-of select="name[position() = ($pos * 5) + 5]"/>
        </span>
      </td>
    </tr>
    </xsl:for-each>
</table>

这就是我试图将JLRishe的答案集成到我现有的XSLT中的方法:

  <!--================-->
  <!--    Categories  -->
  <!--================-->
  <xsl:template name="WriteCategories">
    <xsl:if test="categories">
      <div>
        <!-- set the class, if browsing it's a larger font -->
        <xsl:choose>
          <xsl:when test="$pBrowse='True'">
            <xsl:attribute name="class">critGroup lg</xsl:attribute>
          </xsl:when>
          <xsl:otherwise>
            <xsl:attribute name="class">critGroup</xsl:attribute>
          </xsl:otherwise>
        </xsl:choose>



        <xsl:variable name="numCols" select="5" />

        <xsl:template match="/*">
          <table>
            <xsl:apply-templates select="categories[position() mod $numCols = 1]"
                                 mode="row" />
          </table>
        </xsl:template>

        <xsl:template match="categories" mode="row">
          <tr>
            <xsl:variable name="thisRowItems"
                          select=". | following-sibling::categories[position() &lt; $numCols]" />
            <xsl:apply-templates select="$thisRowItems" />
            <xsl:call-template name="addCells">
              <xsl:with-param name="count" select="$numCols - count($thisRowItems)" />
            </xsl:call-template>
          </tr>
        </xsl:template>

        <xsl:template match="categories">
          <td>
            <xsl:value-of select="."/>
            <span onclick="Critia(this, '{value}')">
              <xsl:value-of select="name" />
            </span>
          </td>
        </xsl:template>

        <xsl:template name="addCells">
          <xsl:param name="count" />

          <xsl:if test="$count > 0">
            <td></td>
            <xsl:call-template name="addCells">
              <xsl:with-param name="count" select="$count - 1" />
            </xsl:call-template>
          </xsl:if>
        </xsl:template>
        <div>
          <!-- if not browsing, write expandable area if there are more than 5 items -->
          <xsl:if test="$pBrowse='False' and count(categories)>5">
            <div id="divCritHdnMore_Category" class="moreHidden">
              <xsl:for-each select="categories">
                <xsl:if test="position()>5">
                  <div>
                    <span onclick="Critia(this, '{value}')">
                      <xsl:value-of select="name" disable-output-escaping="yes" />
                    </span>
                    <xsl:value-of select="concat(' (', count, ')')" />
                  </div>
                </xsl:if>
              </xsl:for-each>
            </div>
          </xsl:if>
        </div>

        <!-- more link -->
        <xsl:if test="$pBrowse='False' and count(categories)>5">
          <div class="moreLink">
            <span id="spnCritMore_Category" onclick="CriteriaMore('Category')">More . . .</span>
          </div>
        </xsl:if>
      </div>
    </xsl:if>
  </xsl:template>

1 个答案:

答案 0 :(得分:0)

这是表行分组的方法。我不认为在最后一行中拥有正确数量的<td>是绝对必要的,但我也添加了这个功能:

将其添加到您希望表格所在位置的WriteCategories模板中:

<table>
  <xsl:apply-templates select="categories[position() mod $numCols = 1]"
                       mode="row" />
</table>

将其添加到任何其他模板之外:

  <xsl:variable name="numCols" select="5" />

  <xsl:template match="categories" mode="row">
    <tr>
      <xsl:variable name="thisRowItems"
                    select=". | following-sibling::categories
                                                   [position() &lt; $numCols]" />
      <xsl:apply-templates select="$thisRowItems" />
      <xsl:call-template name="addCells">
        <xsl:with-param name="count" select="$numCols - count($thisRowItems)" />
      </xsl:call-template>
    </tr>
  </xsl:template>

  <xsl:template match="categories">
    <td>
      <xsl:value-of select="."/>
      <span onclick="Critia(this, '{value}')">
        <xsl:value-of select="name" />
      </span>
    </td>
  </xsl:template>

  <xsl:template name="addCells">
    <xsl:param name="count" />

    <xsl:if test="$count > 0">
      <td></td>
      <xsl:call-template name="addCells">
        <xsl:with-param name="count" select="$count - 1" />
      </xsl:call-template>
    </xsl:if>
  </xsl:template>

在您的样本输入上运行并移除最后3个categories以生成12个项目时,结果为:

<table>
  <tr>
    <td>
    Badges &amp; Holders
    1000111
  <span onclick="Critia(this, '1000111')">Badges &amp; Holders</span></td>
    <td>
    Clips, Tacks &amp; Rubber Bands
    1000113
  <span onclick="Critia(this, '1000113')">Clips, Tacks &amp; Rubber Bands</span></td>
    <td>
    Clocks
    1000114
  <span onclick="Critia(this, '1000114')">Clocks</span></td>
    <td>
    Indexing Flags &amp; Tabs
    1000115
  <span onclick="Critia(this, '1000115')">Indexing Flags &amp; Tabs</span></td>
    <td>
    Magnification
    1000116
  <span onclick="Critia(this, '1000116')">Magnification</span></td>
  </tr>
  <tr>
    <td>
    Pad Holders
    1000117
  <span onclick="Critia(this, '1000117')">Pad Holders</span></td>
    <td>
    Paper Punch Accessories
    1000118
  <span onclick="Critia(this, '1000118')">Paper Punch Accessories</span></td>
    <td>
    Paper Punches
    1000119
  <span onclick="Critia(this, '1000119')">Paper Punches</span></td>
    <td>
    Scissors, Rulers &amp; Paper Trimmers
    1000120
  <span onclick="Critia(this, '1000120')">Scissors, Rulers &amp; Paper Trimmers</span></td>
    <td>
    Signs &amp; Nameplates
    1000121
  <span onclick="Critia(this, '1000121')">Signs &amp; Nameplates</span></td>
  </tr>
  <tr>
    <td>
    Stamps &amp; Pads Accessories
    1000122
  <span onclick="Critia(this, '1000122')">Stamps &amp; Pads Accessories</span></td>
    <td>
    Stapler Accessories
    1000123
  <span onclick="Critia(this, '1000123')">Stapler Accessories</span></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
</table>