Frage

Ich brauche diese XML,

<list columns="3">
  <item>martin</item>
  <item>donald</item>
  <item>whistler</item>
  <item>mother</item>
  <item>carl</item>
  <item>liz</item>
  <item>cosmo</item>
</list>

sehen wie folgt aus:

<table>
  <tr>
    <td>martin</td>
    <td>donald</td>
    <td>whistler</td>
  </tr>
  <tr>
    <td>mother</td>
    <td>carl</td>
    <td>liz</td>
  </tr>
  <tr>
    <td>cosmo</td>
    <td></td>
    <td></td>
  </tr>
</table>

Wenn columns="4", es sollte wie folgt aussehen:

<table>
  <tr>
    <td>martin</td>
    <td>donald</td>
    <td>whistler</td>
    <td>mother</td>
  </tr>
  <tr>
    <td>carl</td>
    <td>liz</td>
    <td>cosmo</td>
    <td></td>
  </tr>
</table>

Für Hinweise auf das, was die XSLT-Datei aussehen sollte? In der Nähe, wie ich sagen kann, ist es eine Art Schleife erfordert (Rekursion?), Aber ich bin nicht sicher, ob es eine elegantere Art und Weise.

War es hilfreich?

Lösung

Der Ansatz, den ich nehmen würde, ist durch Verwendung der ‚mod‘ Funktion der Position () auf jedes Element Elemente in den 1., 4., 7. Positionen entsprechen.

nach jedem derartigen Elemente passende, nur eine Schleife durch die folgenden Geschwister auf der Basis der Spaltenanzahl.

Für die letzte Zeile, wo es nicht genügend Elemente sein kann, um die Zeile zu vervollständigen, gibt es eine rekursive Template in leeren Zellen hinzuzufügen, basierend darauf, wie viele Elemente in der letzten Reihe waren.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

   <!-- Global variable to get column count -->
   <xsl:variable name="columns" select="number(/list/@columns)"/>

   <!-- Match the root node -->
   <xsl:template match="list">
      <table>
         <!-- Match items in the 1st, 4th, 7th positions, etc (or whatever the column variable holds) -->
         <xsl:apply-templates select="item[position() mod $columns = 1]"/>
      </table>
   </xsl:template>

   <xsl:template match="item">
      <tr>
         <!-- Output the current item -->
         <td>
            <xsl:value-of select="."/>
         </td>
         <!-- Output the following items based on the number of required columns -->
         <xsl:for-each select="following-sibling::item[position() &lt; $columns]">
            <td>
               <xsl:value-of select="."/>
            </td>
         </xsl:for-each>
         <!-- Add in any empty cells if numberof following items is not sufficient -->
         <xsl:call-template name="emptycell">
            <xsl:with-param name="cellcounter" select="count(following-sibling::item[position() &lt; $columns]) + 1" />
         </xsl:call-template>
      </tr>
   </xsl:template>

   <!-- Recursive template to add in empty cells when there are not enough items to complete a row -->
   <xsl:template name="emptycell">
      <xsl:param name="cellcounter" />
      <xsl:if test="$cellcounter &lt; $columns">
         <td></td>
         <xsl:call-template name="emptycell">
            <xsl:with-param name="cellcounter" select="$cellcounter + 1" />
         </xsl:call-template>
      </xsl:if>   
   </xsl:template>

</xsl:stylesheet>

Andere Tipps

Etwas, das funktioniert, aber sieht ein bisschen hässlich: Missbrauch Position ()

.
<xsl:param name="columns">4</xsl:param>
<xsl:template match="list">
  <xsl:variable name="theList" select="."/>
  <xsl:for-each select="//*[position()<(count(item) / $columns)]>
    <xsl:variable name="idx" select="position()"/>
    <tr>
    <xsl:for-each select="//*[position()<$columns]">
       <td><xsl:value-of select="$theList/item[position() + $idx * $columns]"/></td>
    </xsl:for-each>
    </tr>
  </xsl:for-each>
</xsl:template>

Es gibt andere Möglichkeiten: zum Beispiel wählen Sie zunächst alle jene Knoten, die mit dem Rest 0 durch Spalten in der Liste unterteilen und dann über diejenigen zu Fuß

.

Siehe http://www.ibm.com/developerworks/library/ x-tipnodst.html für eine längere Beschreibung der Technik oben.

Ich schlage vor, mit CSS3 Spalten . Die Spezifikation wird eine Candidate Recommendation wird (für Implementierungen Bühne nennen) eher bald und wird bereits in Gecko und Webkit (Firefox, Safari, Chrome), mit Anbieter-Präfixen umgesetzt.

Code:

ul { -moz-column-count: 3; -webkit-column-count: 3; }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top