Using C# to transform an xml file using XslTransform.
After being assigned a project at work and becoming extreamly frustrated with the examples I found, I decided to create this tutorial using C# to transform a xml file into a another xml file using XslTransform.
The code below use XSLT to transform an in-house data xml file into a xml file using a clients XSLT specification. This tutorial shows examples of XSLT, extending XSLT with C#, XSLT variables, and <xsl:apply-templates.></xsl:apply-templates.>
Start by creating a standard Console application with the code below. Create the XML and XSLT below and put in the application\bin\debug folder. After running this application in the same folder you should have a Client.xml.
The code is well commented so I will not go on about how things work.
w.WriteStartDocument();
//This creates the link between the xml file and the validation xslt file
//w.WriteDocType("ImportActionCodes",null,"ImportActionCodes.dtd",null);
//Do the work
xslTrans.Transform(xPath,xsltArg,w);
//Close the file
w.Close();
}
}
public class CustomDate
{
//Custom class for creating/getting data
string currentFile = "";
public CustomDate(string xmlFile)
{
//during instan we pass the current xml file we are working on
currentFile = xmlFile;
}
public string GetDate()
{
//Create formatted date for Header/SentDate
System.DateTime dt = System.DateTime.Now;
string sdt = dt.ToString("yyyy-MM-dd");
return sdt;
}
public string GetTime()
{
//Create formatted time for Header/SentTime
System.DateTime dt = System.DateTime.Now;
string sdt = dt.ToString("HH-mm-ss");
return sdt;
}
public string GetValue(string xPath)
{
XmlDocument doc = new XmlDocument();
doc.Load(currentFile);
XmlNode aNode = doc.SelectSingleNode(xPath);
string retVal = aNode.InnerText;
return retVal;
}
public string ConvertDate(string cValue)
{
//Does nothing of real value except showing that you can pass data from the xslt into c#
string retVal = cValue;
return retVal;
}
}
}
Now here is the XML file used for the conversion, save as in-House.xml in
the \bin\debug folder along with the XSLT file.
<?xml version="1.0" encoding="UTF-8"?>
<ACTION_INFORMATION>
<ACTION>
<LOAN_NUM>123456789</LOAN_NUM>
<SERVICER_ID>GreatClient</SERVICER_ID>
<CASE_ID>ABCD_1234</CASE_ID>
<MILESTONE_INFORMATION>
<MS>
<MS_NAME>File Received</MS_NAME>
<MS_SCHEDULED_DATE>2002-02-27T-00-00</MS_SCHEDULED_DATE>
<MS_SEQ>1</MS_SEQ>
</MS>
<MS>
<MS_NAME>BK Case Filed (Generic)</MS_NAME>
<MS_SCHEDULED_DATE>2002-02-19T-00-00</MS_SCHEDULED_DATE>
<MS_SEQ>2</MS_SEQ>
</MS>
<MS>
<MS_NAME>Figures Requested</MS_NAME>
<MS_SCHEDULED_DATE>2004-10-07T-00-00</MS_SCHEDULED_DATE>
<MS_SEQ>3</MS_SEQ>
</MS>
</MILESTONE_INFORMATION>
</ACTION>
</ACTION_INFORMATION>
Here is the XSLT file used for transformation, save as Action.xsl
<!–XSLT Tutorial / Programmer: Sean Rhone / Created: 10/21/2004 –>
<!–this xmlns is standard and should be in all This defines our custom namespace –>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns:sDate="urn:sentDate">
<!– The template match="/" means match every / found in a xml file–>
<xsl:template match="/">
<!– This is a hard coded element to create as is the <Header></Header>–>
<ImportActionCodes>
<Header>
<BusinessPartnerID>123456789</BusinessPartnerID>
<!– Notice select="sDate:GetDate() and GetTime()–>
<!– This calles the GetDate/GetTime methods in the C# code–>
<SentDate><xsl:value-of select="sDate:GetDate()"/></SentDate>
<SentTime><xsl:value-of select="sDate:GetTime()"/></SentTime>
<FromWebMail>Somebody@YourISP.com</FromWebMail>
<TransactionCount>2</TransactionCount>
</Header>
<!– As any programming language there are variables–>
<!– This call creates a variable named "LoanNum" which can be used globaly–>
<xsl:variable name="LoanNum" select="ACTION_INFORMATION/ACTION/LOAN_NUM" />
<!– I want to handle repeating sections of the xml –>
<xsl:for-each select="ACTION_INFORMATION/ACTION/MILESTONE_INFORMATION/MS">
<!– if the current element name equals then we do some work–>
<xsl:if test="MS_NAME='File Received'">
<!– Test string for lenght string-lenght is actually a XPath function–>
<xsl:if test="string-length(MS_SCHEDULED_DATE)>0">
<AOD>
<!–Create a <Account> element and populate with the LoanNum variable–>
<!– NOTE you must use a $ before the variable–>
<Account><xsl:value-of select="$LoanNum"/></Account>
<!–substring() is another XPath function but the idea here is –>
<!–to show passing a value back to C# for some sort of processing –>
<Date><xsl:value-of select="sDate:ConvertDate(substring(MS_SCHEDULED_DATE,1,10))"/></Date>
</AOD>
</xsl:if>
</xsl:if>
<xsl:if test="MS_NAME='BK Case Filed (Generic)'">
<xsl:if test="string-length(MS_SCHEDULED_DATE)>0">
<CFD>
<Account><xsl:value-of select="$LoanNum"/></Account>
<Date><xsl:value-of select="sDate:ConvertDate(substring(MS_SCHEDULED_DATE,1,10))"/></Date>
<!–This call show how to apply some rules to a select elemets –>
<!–If this were a html out you could change font/color etc –>
<!–Here I just show you how to call and create a new element, the important –>
<!–thing to know is the <xsl:template match="MS_SEQ"> matches the current element name –>
<xsl:apply-templates select="MS_SEQ" />
</CFD>
</xsl:if>
</xsl:if>
<xsl:if test="MILESTONE_NAME='Figures Requested'">
<xsl:if test="string-length(MS_SCHEDULED_DATE)>0">
<COTD>
<Account><xsl:value-of select="$LoanNum"/></Account>
<Date><xsl:value-of select="sDate:ConvertDate(substring(MS_SCHEDULED_DATE,1,10))"/></Date>
</COTD>
</xsl:if>
</xsl:if>
</xsl:for-each>
</ImportActionCodes>
</xsl:template>
<xsl:template match="
;MS_SEQ&
quot;>
<MILE_SEQ>
<xsl:value-of select="." />
</MILE_SEQ>
</xsl:template>
</xsl:stylesheet>
Download Code












No comments yet... Be the first to leave a reply!