使用XSLT 2.0验证IBAN?

时间:2011-01-07 10:00:24

标签: xslt xpath xslt-2.0 xpath-2.0 iban

是否可以编写一个可以进行基本IBAN Mod-97检查的XSLT函数?

来自维基百科:
1.将四个初始字符移动到字符串的末尾 2.用两位数字替换字符串中的每个字母,从而扩展字符串,其中A = 10,B = 11,...,Z = 35。
3.将字符串解释为十进制整数,并在除以97时计算该数字的余数。

如果余数为1,则传递校验数字测试并且IBAN可能有效。

感谢。

2 个答案:

答案 0 :(得分:4)

此转化

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

应用于此XML文档时

<t>GB82WEST12345698765432</t>

生成想要的正确结果

true

请注意:函数my:isIBAN()可以作为单个XPath 2.0表达式实现。出于可读性的原因,我没有提供它。

答案 1 :(得分:2)

只是为了好玩(我没有看到@Dimitre已经回答了它)

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

使用此输入:

<IBAN>GB82WEST12345698765432</IBAN>

输出:

Validated IBAN

编辑:更好的一个班轮。