Languages XML-based Code Generation with CodeSmith

XML-based Code Generation with CodeSmith

As you undoubtedly know, XML has become ubiquitous as a data storage and transmission format. It’s possible to build an entire computing infrastructure on top of XML files, and many development shops have done just that. XML-aware tools are an important part of the picture, and in this article I’ll demonstrate how one such tool, the CodeSmith code generator, can use XML files as input. Because CodeSmith templates can contain as much programming logic as you need, this opens up possibilities for transforming XML in ways that would be difficult or impossible using conventional XML tools.


CodeSmith Overview

Here’s the finished template, which will rearrange information from the XML file into an HTML file, as well as performing a simple calculation on the way:


<%@ CodeTemplate Language=”C#” TargetLanguage=”HTML”
Description=”Generate friendly testing report” %>
<%@ XmlProperty Name=”TestReport” Schema=”TestReport.xsd”
Optional=”False” Category=”Data” Description=”Raw test results.” %>
<html>
<head>
<title>Test Report</title>
</head>
<body>
<h1><%= TestReport.ProjectName %></h1>
<h2>Test Date: <%= TestReport.TestDate %></h2>
<h3>Results:</h3>
<table border=”1″ cellpadding=”1″ cellspacing=”1″>
<tr><th>#</th><th>Test</th><th>Result</th></tr>
<% int passedTests = 0; %>
<% for (int i = 0; i < TestReport.Tests.Count; i++) { %>
<tr><td><%= TestReport.Tests[i].TestNumber %></td>
<td><%= TestReport.Tests[i].TestName %></td>
<% if (TestReport.Tests[i].Passed) { passedTests++; %>
<td>Passed</td>
<% } else { %>
<td>Failed</td>
<% } %></tr>
<% } %>
</table>
<p>
<p>Passed <%= passedTests %> out of <%= TestReport.Tests.Count %> Tests
(<%= (passedTests*100)/TestReport.Tests.Count %>%).</p>
</body>
</html>

Generating the Report


The template may look like a step backwards in our quest to simplify things for human consumption, but this is the programming part of the job. Ideally, you only develop a code template once, and then you use it over and over again. But if you tease apart the HTML code (which CodeSmith copies to the output) from the scripting code (which CodeSmith runs) it’s really not that complex. <%= %> token pairs hold variables that CodeSmith evaluates at runtime; the result of the evaluation is what gets written to the output. <% %> token pairs contain scripting code (in C# in this particular template) that the CodeSmith engine runs. Everything else just gets copied over intact.


At run time, the TestReport property will display a builder button in the CodeSmith user interface. Clicking this button opens a file open dialog box which allows the user to browse for an appropriate XML file to use as a metadata source:

CodeSmith will display all the XML files in the folder and let the user choose any one of them to use as the source for the template’s metadata, but an attempt to use a file that doesn’t match the specified schema will result in an error. Selecting an appropriate XML file lets you proceed with code generation. For example, using the XML file that you saw earlier in the article yields this output:


<html>
<head>
<title>Test Report</title>
</head>
<body>
<h1>Inventory Project</h1>
<h2>Test Date: 8/5/2005 12:00:00 AM</h2>
<h3>Results:</h3>
<table border=”1″ cellpadding=”1″ cellspacing=”1″>
<tr><th>#</th><th>Test</th><th>Result</th></tr>
<tr><td>1</td>
<td>Basic data entry</td>
<td>Passed</td>
</tr>
<tr><td>2</td>
<td>Advanced data entry</td>
<td>Failed</td>
</tr>
<tr><td>3</td>
<td>Basic reporting</td>
<td>Passed</td>
</tr>
<tr><td>4</td>
<td>Advanced reporting</td>
<td>Passed</td>
</tr>
<tr><td>5</td>
<td>Inventory reconciliation</td>
<td>Failed</td>
</tr>
</table>
<p>
<p>Passed 3 out of 5 Tests
(60%).</p>
</body>
</html>

Of course, it looks better in a browser:

The generated test report

Working Smarter is the Key


The key to using XML effectively is to remember that it’s a tool. Putting your data into XML files should not be an end in itself – a fact which some developers seem to lose sight of in their drive to become checklist-compliant. Tools such as CodeSmith can help you unlock the data in XML files and make it a useful part of your development process. If your organization has standardized on XML files as a place to store data, you can use CodeSmith to get that data back out and build useful files, tools, and artifacts with it. What more could anyone ask of a developer?


About the Author


Mike Gunderloy is the author of over 20 books and numerous articles on development topics, and the lead developer for Larkware. Check out his latest books, Coder to Developer and Developer to Designer, both from Sybex. When he’s not writing code, Mike putters in the garden on his farm in eastern Washington state.

Latest Posts

Related Stories