Это преобразование :
<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. Я не предоставил это для удобства чтения.