3

基本的なIBAN Mod-97チェックを実行できるXSLT関数を書くことは可能ですか?

ウィキペディアから:
1. 最初の 4 文字を文字列の末尾に移動します。
2. 文字列の各文字を 2 桁に置き換えて、文字列を拡張します。ここで、A=10、B=11、...、Z=35 です。
3. 文字列を 10 進整数として解釈し、その数値を 97 で割った余りを計算します。

余りが 1 の場合、チェック ディジット テストに合格し、IBAN が有効である可能性があります。

ありがとう。

4

2 に答える 2

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 式として実装できます。読みやすさのために提供しませんでした。

于 2011-01-07T14:39:13.153 に答える
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

編集:より良いワンライナー。

于 2011-01-07T15:50:22.020 に答える