2011-01-04 6 views
1

for-each 루프가있는 XSL 파일이 있고 일부 추가 기능 (즉, 문자열 패딩)을주기 위해 EXSLT 프로세서를 사용하고 있습니다.가장 긴 필드 길이의 XSL 패딩

내가 할 수 있기를 원하는 것은 모든 필드를 채우고 그 필드에 대한 가장 긴 레코드의 길이가되도록하는 것입니다. 예를 들어, 각 이름이 가장 긴 이름만큼 긴 다음 가장 긴 레코드 번호만큼 채워질 각 레코드 번호에 대해.

희망 사항을 설명했습니다.

미리 감사드립니다.

답변

4
<xsl:variable name="maxLength"> 
    <xsl:for-each select="name"> 
    <xsl:sort select="string-length(.)" data-type="number" /> 
    <xsl:if test="postion() = last()"> 
     <xsl:value-of select="string-length(.)" /> 
    </xsl:if> 
    </xsl:for-each> 
</xsl:variable> 
+0

+1 좋은 답변입니다. –

+0

이것은 XSLT 2.0 경로를 따라 가지 않고도 필요한 모든 것을 제공합니다. – m4rc

1

C#을 사용하면 Saxon 9 또는 XQSharp와 같은 XSLT 2.0 프로세서로 이동 한 다음 항목의 최대 길이를 쉽게 찾고 http://www.xsltfunctions.com/xsl/functx_pad-string-to-length.html과 같은 기능을 사용하여 패드를 패딩 할 수 있습니다. XSLT 1.0 및 EXSLT로 사용하려면 http://www.exslt.org/math/functions/max/index.html을 사용하여 최대 값을 찾고 http://www.dpawson.co.uk/xsl/sect2/padding.html의 해답을 사용하여 채 웁니다. 그냥 재미를 위해

+0

내가 링크 갈 줄 어떻게 볼 나는 ... 빨리 답장을 보내 주셔서 감사합니다! – m4rc

+0

@Martin xsltfunctions.com의 기능을 어떻게 사용할 수 있는지 알고 있습니까? 복사하고 내 .xsl 안에 붙여 넣으려고했지만 작동하지 않습니다. 아마 내가 어디에 넣어야할지 모르니까. 어쩌면 내가이 모든 파일 http://www.xsltfunctions.com/xsl/functx-1.0-doc-2007-01.xsl을 다운로드하고 내 .xsl에 어떤 식 으로든 포함시켜야합니까? 감사! – bluish

+0

이 푸르스름한 경우 XSLT 2.0 프로세서 (예 : Saxon 9 또는 AltovaXML Tools)를 XSLT 2.0 코드로 사용하는 한 XSLT 스타일 시트에 파일을 포함하거나 가져올 수 있어야합니다. 물론 HTTP를 통한/가져 오기는 효율적이지 않으므로 파일을 한 번 다운로드 한 다음 로컬 사본을 포함/가져와야합니다. 또한 웹 사이트의 단일 기능을 스타일 시트에 복사/붙여 넣기 할 수 있습니다. 네임 스페이스를 정의해야합니다. xmlns : xs = "http://www.w3.org/2001/XMLSchema"및' xmlns : functx = "http://www.functx.com"을'xsl : stylesheet' 엘리먼트에 추가하십시오. –

2

,이 스타일 시트 :

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:variable name="vMaxLengthIds"> 
     <xsl:for-each select="/table/tr[1]/*"> 
      <xsl:variable name="vPosition" select="position()"/> 
      <xsl:for-each select="/table/tr/*[$vPosition]"> 
       <xsl:sort select="string-length(.)" data-type="number" /> 
       <xsl:if test="position() = last()"> 
        <xsl:value-of select="concat('|',generate-id(),'|')" /> 
       </xsl:if> 
      </xsl:for-each> 
     </xsl:for-each> 
    </xsl:variable> 
    <xsl:variable name="vMaxLength" 
        select="/table/tr/*[contains(
             $vMaxLengthIds, 
             concat('|',generate-id(),'|'))]"/> 
    <xsl:variable name="vPaddingMask" 
        select="'            '"/> 
    <xsl:template match="tr"> 
     <xsl:apply-templates/> 
     <xsl:text>&#xA;</xsl:text> 
    </xsl:template> 
    <xsl:template match="td"> 
     <xsl:apply-templates/> 
     <xsl:text> | </xsl:text> 
    </xsl:template> 
    <xsl:template match="th"> 
     <xsl:apply-templates/> 
     <xsl:text> + </xsl:text> 
    </xsl:template> 
    <xsl:template match="tr/*/text()"> 
     <xsl:variable name="vPosition" 
         select="count(../preceding-sibling::*)"/> 
     <xsl:value-of 
      select="concat(
         ., 
         substring(
          $vPaddingMask, 
          1, 
          string-length(
           $vMaxLength[count(preceding-sibling::*) 
              = $vPosition]) 
          - string-length()))"/> 
    </xsl:template> 
</xsl:stylesheet> 

이 입력으로 :

<table> 
    <tr> 
     <th>Day</th> 
     <th>Month</th> 
     <th>Year</th> 
    </tr> 
    <tr> 
     <td>1</td> 
     <td>January</td> 
     <td>2011</td> 
    </tr> 
    <tr> 
     <td>31</td> 
     <td>June</td> 
     <td>2011</td> 
    </tr> 
    <tr> 
     <td>11</td> 
     <td>February</td> 
     <td>2011</td> 
    </tr> 
</table> 

출력 :

Day + Month + Year + 
1 | January | 2011 | 
31 | June  | 2011 | 
11 | February | 2011 | 
+0

그건 실제로 정말 멋진 솔루션입니다! – m4rc