XSLT الى قائمة تتحول إلى طاولة المفاوضات مع الأعمدة قررت حيوي

StackOverflow https://stackoverflow.com/questions/1634269

  •  06-07-2019
  •  | 
  •  

سؤال

وانا بحاجة الى هذا 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>

لتبدو مثل هذا:

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

عند columns="4"، فإنه ينبغي أن تبدو هذه:

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

وأي تلميحات بشأن ما ينبغي أن ننظر ملف XSLT مثل؟ قرب ما استطيع ان اقول، فإنه يتطلب نوعا من حلقة (العودية؟)، ولكن لست متأكدا مما إذا كان هناك طريقة أكثر أناقة.

هل كانت مفيدة؟

المحلول

والنهج وأود أن أنتهز هو تطابق العناصر في 1، 4، مواقف 7TH باستخدام وظيفة "وزارة الدفاع" الموقف () على كل بند.

وبعد مطابقة كل بند من هذه البنود، مجرد حلقة من خلال الأشقاء التالية استنادا إلى عدد الأعمدة.

لفي الصف الأخير، حيث قد يكون هناك عناصر كافية لإكمال الصف، ليس هناك قالب عودي إلى إضافة في الخلايا الفارغة استنادا إلى عدد العناصر كانوا في الصف الأخير.

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

نصائح أخرى

وشيء يعمل، ولكن يبدو قليلا القبيح: موقف تعاطي ()

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

وهناك طرق أخرى: على سبيل المثال اختيار أول كل هذه العقد التي تفرق مع بقية 0 أعمدة في القائمة، ومن ثم السير على تلك

.

http://www.ibm.com/developerworks/library/ س tipnodst.html للحصول على وصف أطول من تقنية أعلاه.

وأقترح استخدام الأعمدة CSS3 . مواصفات ستصبح توصية المرشح (الدعوة إلى مرحلة التنفيذ) بدلا قريبا، ويتم تنفيذه بالفعل في أبو بريص وبكت (فايرفوكس، وسفاري، كروم)، مع البادئات بائع.

والرمز:

ul { -moz-column-count: 3; -webkit-column-count: 3; }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top