Merge HTML Template with XML Data Source

I was recently working on a project where I needed to create an HTML receipt for a client. Instead of building the HTML on the fly I decided to keep the data and display separate. My goal was to create a mail-merge type of process where XML is referenced in an HTML template. I accomplished this using XSLT. This article explains the steps I performed to complete this process.

I began by adding the details of my receipt into XML using the XmlDocument object. To make this easier I added some helper extensions to my project. These extensions make it easy to add child nodes and attributes:
Next, I created the XML. Here is a sample with some random ids, names, and prices that would normally be fetched from a DataSource:
So what does this output look like? To see for yourself you can set a break-point after the code, and run it. Hover over the xml variable and look at the InnerXml. The above code generates the following XML structure:
Next, I created an XSLT file. I usually place this in the project's bin > Debug folder so it is easily referenced after publishing (nugets typically do this too). If you don't see that directory in your Solution Explorer click on the "Show All Files" icon in the top toolbar of that window. Right-click on the Debug folder > Add > New Item > Data > XSLT File. Give it a name like InvoiceTemplate.xslt then Add.

A new file will be created with some pre-generated code. We will replace the contents xsl:template with our own HTML page:
Let's dissect this a bit. A large portion of this is the HEAD section with some inline CSSS. In the BODY you will notice a reference to:
Since the first node is "order" then it is a reference to it's id attribute. Next, I built a table to show the items. Notice a loop around the TR tags with the following call:
The select attribute targets the items/item nodes using XPATH. For each ITEM in our XML it will generate a new row. Our first column is for row numbers and set using the position() function. It outputs the current loop iteration index starting with 1. For the second column we read the name attribute from ITEM much like we did the order id. In the third column we take it a step further by retrieving the price and also formatting it:
This will convert the price to US currency using a leading dollar sign, thousands separator, and a two digit remainder. After we exit the loop there is a "Total" row. That cell includes the sum() function:
It tallies the prices for all ITEM nodes and formats the resulting number to US currency.

Next, we need to merge the XML and XSLT. I used the following class to return me a string. It reads your XSLT file into an XmlReader and passes it to an XslCompiledTransform object. It then calls that object's Transform method passing in our XML. It returns the modified output as a string.
Finally, I called this class to retrieve the HTML. To see it in action I created the folder C:Testing. The following code will generate and open an HTML file on the fly with the string you provide:
Give it a try. If you don't see anything then it could be due to the parser not liking empty tags. I've had issues with leaving the tag blank, or including empty tags. When everything works you should get something like this:


That’s about it. Take your HTML and create a page or plug it into an SmtpClient request and send it as a richtext email. Download my sample project if desired.

Read More