2011-01-07 79 views
3

是否可以編寫一個可以執行基本IBAN Mod-97檢查的XSLT函數?使用XSLT 2.0驗證IBAN?

維基百科:
1.將四個首字符移到字符串的末尾。
2.替換串中的每個字母有兩個數字,從而擴大了的字符串,其中A = 10,B = 11,...,Z = 35。
3.將字符串解釋爲十進制整數,並計算除97以外的數字的餘數。

如果餘數爲1,則將傳遞校驗位數測試並且IBAN可能有效。

謝謝。

+0

好問題,+1。查看我的答案,獲得完整而簡單的解決方案。 :) – 2011-01-07 14:39:47

回答

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表達式來實現。由於可讀性的原因,我沒有提供它。

+0

+1很好的答案。 (它看起來像我們都讀過相同的維基articule,ja!) – 2011-01-07 15:53:20

+0

爲你們倆+1。 2.0是最終的。 – Flack 2011-01-07 19:42:33

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 

編輯:更好的一個班輪。