XSLT는 열이 동적으로 결정된 열로 목록을 표로 변환합니다.
-
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 파일의 모습에 대한 힌트가 있습니까? 내가 알 수 있듯이, 그것은 일종의 루프 (재귀?)가 필요하지만 더 우아한 방법이 있는지 확실하지 않습니다.
해결책
내가 취해야 할 접근법은 각 항목에서 위치 ()의 'mod'함수를 사용하여 1, 4, 7 위의 항목을 일치시키는 것입니다.
이러한 각 항목과 일치 한 후 열에 따라 다음 형제 자매를 반복하십시오.
행을 완성하기에 불충분 한 항목이 불충분 할 수있는 마지막 행의 경우 마지막 행에 몇 개의 항목 수에 따라 빈 셀에 추가 할 재귀 템플릿이 있습니다.
<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() < $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() < $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 < $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>
다른 방법이 있습니다 : 예를 들어, 먼저 목록의 열별로 REST 0으로 나누는 모든 노드를 먼저 선택한 다음 그 위에 걸어갑니다.
보다 http://www.ibm.com/developerworks/library/x-tipnodst.html 위의 기술에 대한 더 긴 설명을 위해.
사용하는 것이 좋습니다 CSS3 열. 이 사양은 곧 후보 추천 (구현 단계)이 될 것이며, 오히려 곧 벤더 접두사와 함께 Gecko and Webkit (Firefox, Safari, Chrome)에서 이미 구현되었습니다.
암호:
ul { -moz-column-count: 3; -webkit-column-count: 3; }
제휴하지 않습니다 StackOverflow