开发者

XSL padding to the longest field length

I have an XSL file which has a for-each loop in it and I am using an EXSLT processor to give some added functionality (namely the string padding).

what I want to be able to do is pad out all fields so they are the length of the longest record for that field. For example, for each name to be as long as the longest name, and then for each record number to be padded as long as the longest record number.

Hope I have explained this okay.

Thanks i开发者_开发技巧n advance.


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


Just for fun, this stylesheet:

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

With this input:

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

Output:

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


With C# you could move to an XSLT 2.0 processor like Saxon 9 or XQSharp and then you can easily find the maximum length of your items and use a function like http://www.xsltfunctions.com/xsl/functx_pad-string-to-length.html to pad them. If you want to do it with XSLT 1.0 and EXSLT then use http://www.exslt.org/math/functions/max/index.html to find the maximum and use a solution in http://www.dpawson.co.uk/xsl/sect2/padding.html to pad.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜