Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validate IBAN using XSLT 2.0?

is it possible to write an XSLT function which can do the basic IBAN Mod-97 check?

From Wikipedia:
1. Move the four initial characters to the end of the string.
2. Replace each letter in the string with two digits, thereby expanding the string, where A=10, B=11, ..., Z=35.
3. Interpret the string as a decimal integer and compute the remainder of that number on division by 97.

If the remainder is 1, the checks digits test is passed and the IBAN may be valid.

Thanks.

like image 982
oneone Avatar asked Dec 07 '25 09:12

oneone


1 Answers

This transformation:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:my="my:my">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:variable name="vCaps" select=
     "'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>

 <xsl:template match="text()">
  <xsl:sequence select="my:isIBAN(.)"/>
 </xsl:template>

 <xsl:function name="my:isIBAN" as="xs:boolean">
  <xsl:param name="pString" as="xs:string"/>

  <xsl:variable name="vDigits" select=
   "string-join(
                (for $vStarting4 in substring($pString, 1,4),
                     $vRest in substring($pString, 5),
                     $vNewString in concat($vRest,$vStarting4),
                     $vLen in string-length($vNewString),
                     $i in 1 to $vLen
                   return
                     my:code(substring($vNewString,$i,1))
                 ),
                 ''
                 )
   "/>

   <xsl:sequence select="xs:integer($vDigits) mod 97 eq 1"/>
 </xsl:function>

 <xsl:function name="my:code" as="xs:string">
  <xsl:param name="pChar" as="xs:string"/>

  <xsl:sequence select=
  "if(string-length($pChar) ne 1 or not(contains($vCaps, $pChar)))
     then $pChar
     else
      xs:string
         (string-to-codepoints($pChar) - string-to-codepoints('A') +10)
  "/>
 </xsl:function>
</xsl:stylesheet>

when applied on this XML document:

<t>GB82WEST12345698765432</t>

produces the wanted, correct result:

true

Do note: The function my:isIBAN() can be implemented as a single XPath 2.0 expression. I didn't provide it for reasons of readability.

like image 185
Dimitre Novatchev Avatar answered Dec 09 '25 23:12

Dimitre Novatchev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!