In this article, I will discuss about validating XML against defined XSL. Prior to getting into this article, it's mandatory that one should have basic knowledge on what XML & XSL are.
Consider the below XML as input (UserCheck.xml) to our application
<?xml
version="1.0"
encoding="utf-16"?>
<root
xmlns:func="urn:actl-xslt">
<User>
<UserName>suryaprakash</UserName>
<Password>password</Password>
</User>
</root>
This example describes the below business rules:
- If UserName, Password node not exists,
generate XML ERROR as output
- If UserName, Password nodes are empty,
generate XML ERROR as output
- Check if user,password exists in DB or not
& generate XML SUCCESS or ERROR as output
The output would be as follows if there are any errors,
which will be inserted into an XML file (result.xml)
Each ERROR tag would represent each error with ERRORMSG & ERRORCODE
<root
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:func="urn:actl-xslt">
<OUTPUT>
<ERROR>
<ErrorMsg>
UserName Node Contains Invalid Data
</ErrorMsg>
<ErrorCode>
ERR_003
</ErrorCode>
</ERROR>
</OUTPUT>
</root>
Let get into the sample with below steps
- Step 1: Define XML
- Step 2: Define XSL as per our business
rules defined above
- Step 3: Define function which will be
called from XSL
- Step 4: Implement code validate XML with
XSL as follows which will be called from XSL
Step 1: Define XML
Consider the below XML as input to our example
<?xml
version="1.0"
encoding="utf-16"?>
<root
xmlns:func="urn:actl-xslt">
<User>
<UserName>suryaprakash</UserName>
<Password>password</Password>
</User>
</root>
Step 2: Define XSL as per our business rules
defined above
<?xml
version="1.0"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:func="urn:actl-xslt">
<xsl:template
match="root">
<root>
<xsl:for-each
select="User">
<OUTPUT>
<xsl:if
test="not(UserName)">
<ERROR>
<ErrorMsg>
UserName Node not present
</ErrorMsg>
<ErrorCode>
ERR_001
</ErrorCode>
</ERROR>
</xsl:if>
<xsl:if
test="not(Password)">
<ERROR>
<ErrorMsg>
Password Node not present
</ErrorMsg>
<ErrorCode>
ERR_002
</ErrorCode>
</ERROR>
</xsl:if>
<xsl:if
test="UserName=''">
<ERROR>
<ErrorMsg>
UserName Node Contains Invalid Data
</ErrorMsg>
<ErrorCode>
ERR_003
</ErrorCode>
</ERROR>
</xsl:if>
<xsl:if
test="Password=''">
<ERROR>
<ErrorMsg>
Password Node Contains Invalid Data
</ErrorMsg>
<ErrorCode>
ERR_004
</ErrorCode>
</ERROR>
</xsl:if>
<xsl:value-of
select="func:checkUserExist('UserName','Password')"
/>
</OUTPUT>
</xsl:for-each>
</root>
</xsl:template>
</xsl:stylesheet>
For the above XSL, the below are code comments
Code Comment #1
xmlns:func="urn:actl-xslt"
Note the attribute that I have added here as - xmlns:func="urn:actl-xslt"
Code Comment #2
The prefix added to my external method
func:checkUserExist('UserName','Password') as
below
<xsl:value-of
select="func:checkUserExist('UserName','Password')"
/>
Code Comment #3
<xsl:if
test="not(UserName)">
This tag is used to check if USERNAME node exists or not
Code Comment #4
<xsl:if
test="UserName=''">
This tag is used to check if content in USERNAME node is empty or not
Step 3: Define a function which will be called from XSL
This function will be called from XSL defined as <xsl:value-of select="func:checkUserExist('UserName','Password')"
/>
Instead of checking username against DB we are checking with a static value. If
username matches it returns a Success string else it would return ErrorStrings
public
string checkUserExist(string
uName, string pWord)
{
string returnValue =
string.Empty;
if (uName ==
"prakash")
{
returnValue = " <SUCCESS> <SuccessMsg>
SUCESSS </SuccessMsg><SuccessCode>SUC_000</SuccessCode> </SUCCESS> ";
}
else
{
returnValue = " <ERROR> <ErrorMsg>UserName/Password
is invalid!.</ErrorMsg><ErrorCode>ERR_005</ErrorCode> </ERROR> ";
}
return returnValue;
}
Step 4: Implement code to validate XML with XSL as follows which will be called
from XSL.
This below function will be called in the main method & this function declares 3 main
variables for XML input, XSL input & XML output as result.xml
public void
CheckUserXslt()
{
string sourceDoc =
@"D:\Surya
Prakash\WorkAround\GopalSample\XML\CheckUser.XML";
string xsltDoc =
@"D:\Surya
Prakash\WorkAround\GopalSample\XML\CheckUser.xslt";
string resultDoc =
@"D:\Surya
Prakash\WorkAround\GopalSample\XML\result.xml";
XsltArgumentList xsltArguments =
null;
XsltExtension xsltExtension =
new XsltExtension();
xsltArguments = new
XsltArgumentList();
xsltArguments.AddExtensionObject("urn:actl-xslt",
xsltExtension);
XPathDocument myXPathDocument =
new XPathDocument(sourceDoc);
XslTransform myXslTransform =
new XslTransform();
XmlTextWriter writer =
new XmlTextWriter(resultDoc,
null);
myXslTransform.Load(xsltDoc);
myXslTransform.Transform(myXPathDocument, xsltArguments, writer);
writer.Close();
StreamReader stream =
new StreamReader(resultDoc);
}
Finally run the application by modifying the input XML & see the output in
result.xml
Happy Coding… Hope this helps!