Topic
  • 3 replies
  • Latest Post - ‏2014-01-14T17:10:07Z by urgrand
urgrand
urgrand
8 Posts

Pinned topic Internation bank account number validation in DataPower ?

‏2014-01-14T03:20:01Z |

hi, I am trying to validate international bank account number in DataPower, below is the xslt 2.0 code which does it, but DataPower is not supporting some of these xslt2.0 functions, can anyone suggest on how we can achieve this in the DataPower?

Internationl Bank  Account Number validation details:

  1. Check that the total IBAN length is correct as per the country. If not, the IBAN is invalid
  2. Move the four initial characters to the end of the string
  3. Replace each letter in the string with two digits, thereby expanding the string, where A = 10, B = 11, ..., Z = 35
  4. Interpret the string as a decimal integer and compute the remainder of that number on division by 97

XSLT2.0 Code:

<xsl:stylesheet version="2.0"

 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 xmlns:local="http://localhost/">
    <xsl:template match="IBAN[local:validate(.)]">
        <xsl:text>Validated IBAN</xsl:text>
    </xsl:template>
    <xsl:function name="local:validate">
        <xsl:param name="pIBAN" as="xs:string"/>
        <xsl:sequence select="xs:integer(
                                 codepoints-to-string(
                                    for $n in string-to-codepoints(
                                                 concat(
                                                    substring(
                                                       $pIBAN,
                                                       5
                                                    ),
                                                    substring(
                                                       $pIBAN,
                                                       1,
                                                       4
                                                    )
                                                 )
                                              )
                                    return if ($n > 64)
                                           then string-to-codepoints(
                                                   string(
                                                      $n - 55
                                                   )
                                                )
                                           else $n
                                 )
                              ) mod 97 eq 1"/>
    </xsl:function>
</xsl:stylesheet>

 

INPUT XML:

<IBAN>GB82WEST12345698765432</IBAN>

 

OutPUt:

Validated IBAN

  • HermannSW
    HermannSW
    4720 Posts
    ACCEPTED ANSWER

    Re: Internation bank account number validation in DataPower ?

    ‏2014-01-14T12:32:58Z  

    Hi,

    I just looked up my own German IBAN, its "DE20" followed by 18 digits.

    With v6.0.0.0 firmware DataPower does support XQuery 1.0, which contains XPath 2.0 as subset.
    So the expression above (which I did find on wikipedia with above sample) can be used.

    Problem which arises is that "xs:integer(24 digit number)" raises an overflow error.

    I did workaround this with function "local:mod(_,_)" working up to 30 digits.

    Here you can see that the sample returns true, and the XQuery script:

    $ echo "<IBAN>GB82WEST12345698765432</IBAN>" | coproc2 IBAN.xq - http://dp1-l2:2225 ; echo
    true
    $
    $ cat IBAN.xq
    declare variable $pIBAN := .;

    declare function local:mod($i as xs:string, $m as xs:integer) as xs:integer
    {
      let $pre := string-length($i) - 12
      (: 1e12 mod $m :)
      let $fac := 1000000000000 mod $m

      return (   (xs:integer(substring($i,1,$pre)) mod $m) * $fac
               + (xs:integer(substring($i,$pre+1)) mod $m)
             ) mod $m
    };

    local:mod(
       codepoints-to-string(
          for $n in string-to-codepoints(
                       concat(
                          substring(
                             $pIBAN,
                             5
                          ),
                          substring(
                             $pIBAN,
                             1,
                             4
                          )
                       )
                    )
          return if ($n > 64)
                 then string-to-codepoints(
                         string(
                            $n - 55
                         )
                      )
                 else $n
       ),
       97
    ) eq 1
    $

     

    zorba XQuery processor also complains:
    http://try.zorba.io/queries/xquery/fVIdB7uZjfW04z8h5EuYAxN5mtE%3D

    Running  the code results in:

    [FORG0001] "3214282912345698765432161182": value of type xs:string is not castable to type xs:integer

    Line 3, column 1.

     


    Hermann<myXsltBlog/> <myXsltTweets/> <myCE/> <myFrameless/>
     

    Attachments

    Updated on 2014-01-14T13:02:01Z at 2014-01-14T13:02:01Z by HermannSW
  • HermannSW
    HermannSW
    4720 Posts
    ACCEPTED ANSWER

    Re: Internation bank account number validation in DataPower ?

    ‏2014-01-14T16:04:47Z  
    • HermannSW
    • ‏2014-01-14T12:32:58Z

    Hi,

    I just looked up my own German IBAN, its "DE20" followed by 18 digits.

    With v6.0.0.0 firmware DataPower does support XQuery 1.0, which contains XPath 2.0 as subset.
    So the expression above (which I did find on wikipedia with above sample) can be used.

    Problem which arises is that "xs:integer(24 digit number)" raises an overflow error.

    I did workaround this with function "local:mod(_,_)" working up to 30 digits.

    Here you can see that the sample returns true, and the XQuery script:

    $ echo "<IBAN>GB82WEST12345698765432</IBAN>" | coproc2 IBAN.xq - http://dp1-l2:2225 ; echo
    true
    $
    $ cat IBAN.xq
    declare variable $pIBAN := .;

    declare function local:mod($i as xs:string, $m as xs:integer) as xs:integer
    {
      let $pre := string-length($i) - 12
      (: 1e12 mod $m :)
      let $fac := 1000000000000 mod $m

      return (   (xs:integer(substring($i,1,$pre)) mod $m) * $fac
               + (xs:integer(substring($i,$pre+1)) mod $m)
             ) mod $m
    };

    local:mod(
       codepoints-to-string(
          for $n in string-to-codepoints(
                       concat(
                          substring(
                             $pIBAN,
                             5
                          ),
                          substring(
                             $pIBAN,
                             1,
                             4
                          )
                       )
                    )
          return if ($n > 64)
                 then string-to-codepoints(
                         string(
                            $n - 55
                         )
                      )
                 else $n
       ),
       97
    ) eq 1
    $

     

    zorba XQuery processor also complains:
    http://try.zorba.io/queries/xquery/fVIdB7uZjfW04z8h5EuYAxN5mtE%3D

    Running  the code results in:

    [FORG0001] "3214282912345698765432161182": value of type xs:string is not castable to type xs:integer

    Line 3, column 1.

     


    Hermann<myXsltBlog/> <myXsltTweets/> <myCE/> <myFrameless/>
     

    And here is the DataPower (EXSLT) solution (stylesheet attached as well):

    $ echo "<IBAN>GB82WEST12345698765432</IBAN>" | coproc2 IBAN.xsl - http://dp1-l2:2223 ; echo
    Validated IBAN
    $
    $ cat IBAN.xsl
    <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:iban="urn:iso:std:iso:13616"
      xmlns:func="http://exslt.org/functions"
      xmlns:dp="http://www.datapower.com/extensions"
      extension-element-prefixes="dp"
    >
      <xsl:output omit-xml-declaration="yes" />

      <xsl:template match="IBAN[iban:validate(.)]">
        <xsl:text>Validated IBAN</xsl:text>
      </xsl:template>

      <func:function name="iban:validate">
        <xsl:param name="pIBAN"/>

        <func:result
          select="1 = iban:mod(concat(substring($pIBAN,5), substring($pIBAN,1,4)))"
        />
      </func:function>

      <func:function name="iban:mod">
        <xsl:param name="str"/>
        <xsl:param name="fac" select="1"/>

        <xsl:variable name="len" select="string-length($str)"/>
        <xsl:variable name="chr" select="substring($str, $len)"/>

        <xsl:choose>
          <xsl:when test="not($chr)"><func:result select="0"/></xsl:when>

          <xsl:when test="number($chr) &lt; 10">
            <func:result
              select="( iban:mod( substring($str, 1, $len - 1), (10*$fac) mod 97)
                        + $chr * $fac
                      ) mod 97"/>
          </xsl:when>

          <xsl:otherwise>
            <xsl:variable name="d">
              <xsl:choose>
                <xsl:when test="$chr = 'A'">10</xsl:when>
                <xsl:when test="$chr = 'B'">11</xsl:when>
                <xsl:when test="$chr = 'C'">12</xsl:when>
                <xsl:when test="$chr = 'D'">13</xsl:when>
                <xsl:when test="$chr = 'E'">14</xsl:when>
                <xsl:when test="$chr = 'F'">15</xsl:when>
                <xsl:when test="$chr = 'G'">16</xsl:when>
                <xsl:when test="$chr = 'H'">17</xsl:when>
                <xsl:when test="$chr = 'I'">18</xsl:when>
                <xsl:when test="$chr = 'J'">19</xsl:when>
                <xsl:when test="$chr = 'K'">20</xsl:when>
                <xsl:when test="$chr = 'L'">21</xsl:when>
                <xsl:when test="$chr = 'M'">22</xsl:when>
                <xsl:when test="$chr = 'N'">23</xsl:when>
                <xsl:when test="$chr = 'O'">24</xsl:when>
                <xsl:when test="$chr = 'P'">25</xsl:when>
                <xsl:when test="$chr = 'Q'">26</xsl:when>
                <xsl:when test="$chr = 'R'">27</xsl:when>
                <xsl:when test="$chr = 'S'">28</xsl:when>
                <xsl:when test="$chr = 'T'">29</xsl:when>
                <xsl:when test="$chr = 'U'">30</xsl:when>
                <xsl:when test="$chr = 'V'">31</xsl:when>
                <xsl:when test="$chr = 'W'">32</xsl:when>
                <xsl:when test="$chr = 'X'">33</xsl:when>
                <xsl:when test="$chr = 'Y'">34</xsl:when>
                <xsl:when test="$chr = 'Z'">35</xsl:when>
              </xsl:choose>
            </xsl:variable>

            <func:result
              select="( iban:mod( substring($str, 1, $len - 1), (100*$fac) mod 97)
                        + $d * $fac
                      ) mod 97"
            />
          </xsl:otherwise>
        </xsl:choose>
      </func:function>
    </xsl:stylesheet>
    $

     

    Hermann<myXsltBlog/> <myXsltTweets/> <myCE/> <myFrameless/>

    Attachments

  • HermannSW
    HermannSW
    4720 Posts

    Re: Internation bank account number validation in DataPower ?

    ‏2014-01-14T12:32:58Z  

    Hi,

    I just looked up my own German IBAN, its "DE20" followed by 18 digits.

    With v6.0.0.0 firmware DataPower does support XQuery 1.0, which contains XPath 2.0 as subset.
    So the expression above (which I did find on wikipedia with above sample) can be used.

    Problem which arises is that "xs:integer(24 digit number)" raises an overflow error.

    I did workaround this with function "local:mod(_,_)" working up to 30 digits.

    Here you can see that the sample returns true, and the XQuery script:

    $ echo "<IBAN>GB82WEST12345698765432</IBAN>" | coproc2 IBAN.xq - http://dp1-l2:2225 ; echo
    true
    $
    $ cat IBAN.xq
    declare variable $pIBAN := .;

    declare function local:mod($i as xs:string, $m as xs:integer) as xs:integer
    {
      let $pre := string-length($i) - 12
      (: 1e12 mod $m :)
      let $fac := 1000000000000 mod $m

      return (   (xs:integer(substring($i,1,$pre)) mod $m) * $fac
               + (xs:integer(substring($i,$pre+1)) mod $m)
             ) mod $m
    };

    local:mod(
       codepoints-to-string(
          for $n in string-to-codepoints(
                       concat(
                          substring(
                             $pIBAN,
                             5
                          ),
                          substring(
                             $pIBAN,
                             1,
                             4
                          )
                       )
                    )
          return if ($n > 64)
                 then string-to-codepoints(
                         string(
                            $n - 55
                         )
                      )
                 else $n
       ),
       97
    ) eq 1
    $

     

    zorba XQuery processor also complains:
    http://try.zorba.io/queries/xquery/fVIdB7uZjfW04z8h5EuYAxN5mtE%3D

    Running  the code results in:

    [FORG0001] "3214282912345698765432161182": value of type xs:string is not castable to type xs:integer

    Line 3, column 1.

     


    Hermann<myXsltBlog/> <myXsltTweets/> <myCE/> <myFrameless/>
     

    Attachments

    Updated on 2014-01-14T13:02:01Z at 2014-01-14T13:02:01Z by HermannSW
  • HermannSW
    HermannSW
    4720 Posts

    Re: Internation bank account number validation in DataPower ?

    ‏2014-01-14T16:04:47Z  
    • HermannSW
    • ‏2014-01-14T12:32:58Z

    Hi,

    I just looked up my own German IBAN, its "DE20" followed by 18 digits.

    With v6.0.0.0 firmware DataPower does support XQuery 1.0, which contains XPath 2.0 as subset.
    So the expression above (which I did find on wikipedia with above sample) can be used.

    Problem which arises is that "xs:integer(24 digit number)" raises an overflow error.

    I did workaround this with function "local:mod(_,_)" working up to 30 digits.

    Here you can see that the sample returns true, and the XQuery script:

    $ echo "<IBAN>GB82WEST12345698765432</IBAN>" | coproc2 IBAN.xq - http://dp1-l2:2225 ; echo
    true
    $
    $ cat IBAN.xq
    declare variable $pIBAN := .;

    declare function local:mod($i as xs:string, $m as xs:integer) as xs:integer
    {
      let $pre := string-length($i) - 12
      (: 1e12 mod $m :)
      let $fac := 1000000000000 mod $m

      return (   (xs:integer(substring($i,1,$pre)) mod $m) * $fac
               + (xs:integer(substring($i,$pre+1)) mod $m)
             ) mod $m
    };

    local:mod(
       codepoints-to-string(
          for $n in string-to-codepoints(
                       concat(
                          substring(
                             $pIBAN,
                             5
                          ),
                          substring(
                             $pIBAN,
                             1,
                             4
                          )
                       )
                    )
          return if ($n > 64)
                 then string-to-codepoints(
                         string(
                            $n - 55
                         )
                      )
                 else $n
       ),
       97
    ) eq 1
    $

     

    zorba XQuery processor also complains:
    http://try.zorba.io/queries/xquery/fVIdB7uZjfW04z8h5EuYAxN5mtE%3D

    Running  the code results in:

    [FORG0001] "3214282912345698765432161182": value of type xs:string is not castable to type xs:integer

    Line 3, column 1.

     


    Hermann<myXsltBlog/> <myXsltTweets/> <myCE/> <myFrameless/>
     

    And here is the DataPower (EXSLT) solution (stylesheet attached as well):

    $ echo "<IBAN>GB82WEST12345698765432</IBAN>" | coproc2 IBAN.xsl - http://dp1-l2:2223 ; echo
    Validated IBAN
    $
    $ cat IBAN.xsl
    <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:iban="urn:iso:std:iso:13616"
      xmlns:func="http://exslt.org/functions"
      xmlns:dp="http://www.datapower.com/extensions"
      extension-element-prefixes="dp"
    >
      <xsl:output omit-xml-declaration="yes" />

      <xsl:template match="IBAN[iban:validate(.)]">
        <xsl:text>Validated IBAN</xsl:text>
      </xsl:template>

      <func:function name="iban:validate">
        <xsl:param name="pIBAN"/>

        <func:result
          select="1 = iban:mod(concat(substring($pIBAN,5), substring($pIBAN,1,4)))"
        />
      </func:function>

      <func:function name="iban:mod">
        <xsl:param name="str"/>
        <xsl:param name="fac" select="1"/>

        <xsl:variable name="len" select="string-length($str)"/>
        <xsl:variable name="chr" select="substring($str, $len)"/>

        <xsl:choose>
          <xsl:when test="not($chr)"><func:result select="0"/></xsl:when>

          <xsl:when test="number($chr) &lt; 10">
            <func:result
              select="( iban:mod( substring($str, 1, $len - 1), (10*$fac) mod 97)
                        + $chr * $fac
                      ) mod 97"/>
          </xsl:when>

          <xsl:otherwise>
            <xsl:variable name="d">
              <xsl:choose>
                <xsl:when test="$chr = 'A'">10</xsl:when>
                <xsl:when test="$chr = 'B'">11</xsl:when>
                <xsl:when test="$chr = 'C'">12</xsl:when>
                <xsl:when test="$chr = 'D'">13</xsl:when>
                <xsl:when test="$chr = 'E'">14</xsl:when>
                <xsl:when test="$chr = 'F'">15</xsl:when>
                <xsl:when test="$chr = 'G'">16</xsl:when>
                <xsl:when test="$chr = 'H'">17</xsl:when>
                <xsl:when test="$chr = 'I'">18</xsl:when>
                <xsl:when test="$chr = 'J'">19</xsl:when>
                <xsl:when test="$chr = 'K'">20</xsl:when>
                <xsl:when test="$chr = 'L'">21</xsl:when>
                <xsl:when test="$chr = 'M'">22</xsl:when>
                <xsl:when test="$chr = 'N'">23</xsl:when>
                <xsl:when test="$chr = 'O'">24</xsl:when>
                <xsl:when test="$chr = 'P'">25</xsl:when>
                <xsl:when test="$chr = 'Q'">26</xsl:when>
                <xsl:when test="$chr = 'R'">27</xsl:when>
                <xsl:when test="$chr = 'S'">28</xsl:when>
                <xsl:when test="$chr = 'T'">29</xsl:when>
                <xsl:when test="$chr = 'U'">30</xsl:when>
                <xsl:when test="$chr = 'V'">31</xsl:when>
                <xsl:when test="$chr = 'W'">32</xsl:when>
                <xsl:when test="$chr = 'X'">33</xsl:when>
                <xsl:when test="$chr = 'Y'">34</xsl:when>
                <xsl:when test="$chr = 'Z'">35</xsl:when>
              </xsl:choose>
            </xsl:variable>

            <func:result
              select="( iban:mod( substring($str, 1, $len - 1), (100*$fac) mod 97)
                        + $d * $fac
                      ) mod 97"
            />
          </xsl:otherwise>
        </xsl:choose>
      </func:function>
    </xsl:stylesheet>
    $

     

    Hermann<myXsltBlog/> <myXsltTweets/> <myCE/> <myFrameless/>

    Attachments

  • urgrand
    urgrand
    8 Posts

    Re: Internation bank account number validation in DataPower ?

    ‏2014-01-14T17:10:07Z  
    • HermannSW
    • ‏2014-01-14T16:04:47Z

    And here is the DataPower (EXSLT) solution (stylesheet attached as well):

    $ echo "<IBAN>GB82WEST12345698765432</IBAN>" | coproc2 IBAN.xsl - http://dp1-l2:2223 ; echo
    Validated IBAN
    $
    $ cat IBAN.xsl
    <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:iban="urn:iso:std:iso:13616"
      xmlns:func="http://exslt.org/functions"
      xmlns:dp="http://www.datapower.com/extensions"
      extension-element-prefixes="dp"
    >
      <xsl:output omit-xml-declaration="yes" />

      <xsl:template match="IBAN[iban:validate(.)]">
        <xsl:text>Validated IBAN</xsl:text>
      </xsl:template>

      <func:function name="iban:validate">
        <xsl:param name="pIBAN"/>

        <func:result
          select="1 = iban:mod(concat(substring($pIBAN,5), substring($pIBAN,1,4)))"
        />
      </func:function>

      <func:function name="iban:mod">
        <xsl:param name="str"/>
        <xsl:param name="fac" select="1"/>

        <xsl:variable name="len" select="string-length($str)"/>
        <xsl:variable name="chr" select="substring($str, $len)"/>

        <xsl:choose>
          <xsl:when test="not($chr)"><func:result select="0"/></xsl:when>

          <xsl:when test="number($chr) &lt; 10">
            <func:result
              select="( iban:mod( substring($str, 1, $len - 1), (10*$fac) mod 97)
                        + $chr * $fac
                      ) mod 97"/>
          </xsl:when>

          <xsl:otherwise>
            <xsl:variable name="d">
              <xsl:choose>
                <xsl:when test="$chr = 'A'">10</xsl:when>
                <xsl:when test="$chr = 'B'">11</xsl:when>
                <xsl:when test="$chr = 'C'">12</xsl:when>
                <xsl:when test="$chr = 'D'">13</xsl:when>
                <xsl:when test="$chr = 'E'">14</xsl:when>
                <xsl:when test="$chr = 'F'">15</xsl:when>
                <xsl:when test="$chr = 'G'">16</xsl:when>
                <xsl:when test="$chr = 'H'">17</xsl:when>
                <xsl:when test="$chr = 'I'">18</xsl:when>
                <xsl:when test="$chr = 'J'">19</xsl:when>
                <xsl:when test="$chr = 'K'">20</xsl:when>
                <xsl:when test="$chr = 'L'">21</xsl:when>
                <xsl:when test="$chr = 'M'">22</xsl:when>
                <xsl:when test="$chr = 'N'">23</xsl:when>
                <xsl:when test="$chr = 'O'">24</xsl:when>
                <xsl:when test="$chr = 'P'">25</xsl:when>
                <xsl:when test="$chr = 'Q'">26</xsl:when>
                <xsl:when test="$chr = 'R'">27</xsl:when>
                <xsl:when test="$chr = 'S'">28</xsl:when>
                <xsl:when test="$chr = 'T'">29</xsl:when>
                <xsl:when test="$chr = 'U'">30</xsl:when>
                <xsl:when test="$chr = 'V'">31</xsl:when>
                <xsl:when test="$chr = 'W'">32</xsl:when>
                <xsl:when test="$chr = 'X'">33</xsl:when>
                <xsl:when test="$chr = 'Y'">34</xsl:when>
                <xsl:when test="$chr = 'Z'">35</xsl:when>
              </xsl:choose>
            </xsl:variable>

            <func:result
              select="( iban:mod( substring($str, 1, $len - 1), (100*$fac) mod 97)
                        + $d * $fac
                      ) mod 97"
            />
          </xsl:otherwise>
        </xsl:choose>
      </func:function>
    </xsl:stylesheet>
    $

     

    Hermann<myXsltBlog/> <myXsltTweets/> <myCE/> <myFrameless/>

    Hi Herman,

    Thanks for your prompt response, i am using firmware v5.0, and your EXSLT code worked perfectly.