Hi all,
Could you please let us know the best way to do the below validation in xslt

we are reading card number using an xpath expression

<xsl:value of select ="/*/*/*/cardnumber" />
from input. It is a string of 19 characters. we would like to include a check which will see if the first 15 characters are digits and the next 4 charcters are spaces. What is the best way in xsl to perform this check.

"123456789123456 " is valid
Anything other than this format, should not be accepted. that is which are not, first 15 characters are digits and next 4 characters are spaces.can we use any script within xsl or regex. Please advise.If regex or scripts are to be used, let us know what namespaces to declare as well.

the sample string I have given, lost spaces in it
It should be
"123456789123456<fourspaces>"

Are you trying to do this validation within the XSLT itself? And if it doesn't pass this constraint in the XSLT, what behavior do you want? What versions of XSLT are you using 1.0 or 2.0?

This very much sounds like something that would be better done in XML Schema (or DTDs) on the message itself before it gets a chance to go into your transformation.

If it must be done in the XSLT, what is your definition of a "character"? Or must it be numbers 0-9 ? Let me know and I'll see what I can do.

FYI, Please use codeboxes, then we can see your plain text of what you're doing.

Edited 5 Years Ago by iceandrews: n/a

Andrews,
Thanks for the response.
We are using version 2.0. Client has defined the schemas and as per the defention, the carnumber is a string of 19 characters. We cannot modify that. Now we have to do this in xslt as per the requirement and we have to xsl:terminate=yes, in case if it does not pass the constraint. The first 15 entries should be digits(numbers0-9) and next 4 entries should be spaces.
Sample

"123456789123456    "

Pretty simple. The matches() function allows you to take a string and test it against a regex expression. You wrap some logic around that and you've got your xslt.

INPUT

<R>
	<CN>123456789123456     </CN>
</R>

XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:variable name="qte">'</xsl:variable>

	<xsl:template match="/">
		<xsl:apply-templates select="R/CN"/>
	</xsl:template>

	<xsl:template match="CN">
		<xsl:choose>
			<xsl:when test="matches(string(.),'^[0-9]{15}[\s]{4,4}$')">
				<xsl:value-of select="."/>
			</xsl:when>
			<xsl:otherwise>
				<xsl:message terminate="yes">
					<xsl:value-of select="concat($qte,. ,$qte)"/>
					<xsl:text> does not meet the requirement/</xsl:text>
				</xsl:message>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
</xsl:stylesheet>

Andrews,
I am getting "'matches()' is an unknown XSLT function." while debugging in ms visual studio 2008 edition.

Then you aren't using XSLT 2.0. Microsoft does not support a XSLT 2.0 processor in Visual Studio. This becomes a more complicated problem in XSLT 1.0 But here's a potential solution. I did NOT test it thoroughly, but it appears to be working fairly well. I used the same input document that I defined above.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:variable name="qte">'</xsl:variable>

	<xsl:template match="/">
		<xsl:apply-templates select="R/CN"/>
	</xsl:template>

	<xsl:template match="CN">
		<xsl:choose>
			<xsl:when test="string-length(.) != 19">
				<xsl:call-template name="terminate"/>
			</xsl:when>
			<xsl:otherwise>
				<xsl:choose>
					<xsl:when test="ends-with(.,'    ') and translate(translate(substring(., 1, 15), '1234567890', ''), '','') = ''">
						<xsl:value-of select="." />
					</xsl:when>
					<xsl:otherwise>
						<xsl:call-template name="terminate"/>
					</xsl:otherwise>
				</xsl:choose>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>

	<xsl:template name="terminate">
		<xsl:message terminate="yes">
			<xsl:value-of select="concat($qte,. ,$qte)"/>
			<xsl:text> does not meet the requirement/</xsl:text>
		</xsl:message>
	</xsl:template>
</xsl:stylesheet>
This article has been dead for over six months. Start a new discussion instead.