Skip to content

Instantly share code, notes, and snippets.

@janjouketjalsma
Last active August 13, 2018 09:44
Show Gist options
  • Save janjouketjalsma/1deb5d5455c0bf7f3c1354599f5716b8 to your computer and use it in GitHub Desktop.
Save janjouketjalsma/1deb5d5455c0bf7f3c1354599f5716b8 to your computer and use it in GitHub Desktop.
Transform a string with numbers to a string with padded numbers using XSLT 1.0
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="/">
<xsl:call-template name="padNumbers">
<xsl:with-param name="string">blabfalsbjk432nbhjkhjk432h4kj23</xsl:with-param>
<xsl:with-param name="numberFormat" select="'000'"/>
</xsl:call-template>
</xsl:template>
<!--
Pad all numbers in a string
example 1: ABCD 12 -> ABCD 00012
example 2: A1B2 -> A00001B00002
-->
<xsl:template name="padNumbers">
<xsl:param name="string" select="''"/>
<xsl:param name="numberFormat" select="'00000'"/>
<xsl:param name="numberStack" select="''"/>
<xsl:if test="string-length($string) > 0">
<xsl:variable name="currentChar" select="substring($string,1,1)"/>
<xsl:variable name="currentCharIsNumeric" select="string-length(translate($currentChar, '1234567890', '')) = 0"/>
<xsl:variable name="nextChar" select="substring($string,2,1)"/>
<xsl:variable name="nextCharIsnumeric" select="string-length($nextChar) > 0 and string-length(translate($nextChar, '1234567890', '')) = 0"/>
<xsl:if test="not($currentCharIsNumeric)">
<!-- current char is not numeric so we output it as is -->
<xsl:value-of select="$currentChar"/>
</xsl:if>
<xsl:if test="$currentCharIsNumeric and not($nextCharIsnumeric)">
<!-- next char is not numeric, so pad, then output the numberstack -->
<xsl:value-of select="format-number(number(concat($numberStack, $currentChar)), $numberFormat)"/>
</xsl:if>
<xsl:variable name="newNumberStack">
<xsl:if test="$currentCharIsNumeric and $nextCharIsnumeric">
<!-- expecting more numbers so add current number to stack -->
<xsl:value-of select="concat($numberStack, $currentChar)"/>
</xsl:if>
</xsl:variable>
<!-- recurse into next if there are more characters to process -->
<xsl:if test="string-length($string) > 1">
<xsl:variable name="remaining" select="substring($string,2)"/>
<xsl:variable name="remainingHasNumeric" select="string-length($remaining) > string-length(translate($remaining, '1234567890', ''))"/>
<xsl:choose>
<xsl:when test="$remainingHasNumeric or string-length($newNumberStack) > 0">
<xsl:call-template name="padNumbers">
<xsl:with-param name="string" select="$remaining"/>
<xsl:with-param name="numberStack" select="$newNumberStack"/>
<xsl:with-param name="numberFormat" select="$numberFormat"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$remaining"/>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment