http://www.developer.com/xml/article.php/3525776/XML-based-Code-Generation-with-CodeSmith.htm
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 is a template-driven code generator. CodeSmith templates are written in a language similar to ASP.NET, and may contain scripting code in C#, VB, or JScript. When you use CodeSmith to generate code, the CodeSmith engine combines static content in the template with dynamic metadata that can be supplied in a variety of formats. In particular, CodeSmith can make use of an XML file as a metadata source for a template. This allows you to supply the dynamic part of your generated code in the form of an XML file that gets read and processed by the CodeSmith engine. To use XML metadata in a template, you use an So much for the syntax - let's see an example! For this example, I'm going to use CodeSmith to transform a simple XML file that might be generated by an automated testing tool into a friendlier HTML report. Yes, there are other ways to turn XML into HTML (notably the use of XSL). But with the flexibility of CodeSmith's templates, it's easy to do some things (like perform calculations) that are difficult in pure XSL. Also, this example demonstrates the mechanics of working with XML metadata without the complexity of generating a source code for a full-blown application. One of the key things to keep in mind about a general-purpose code generator is that you can use it to generate any text, not just programming code: SQL statements, HTML pages, and even documentation are all perfectly reasonably outputs as long as you can find patterns in them. So, here's what the raw XML I'm starting with looks like. This is the sort of thing that computers like to see, because they can parse tag soup easily, but it's not so handy for people: To make effective use of this XML file (and others with the same structure) as metadata in CodeSmith, we'll need the corresponding XSD file, TestReport.xsd: Armed with the schema file, I created a new CodeSmith template in the CodeSmith Studio IDE. Figure 1 shows an early stage in writing this template. As you can see, CodeSmith can use the information in the TestReport.xsd schema file (specified in the 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>
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. 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: Of course, it looks better in a browser: 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? 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.
XML-based Code Generation with CodeSmith
August 8, 2005
CodeSmith Overview
The XmlProperty Directive
XmlProperty directive. This directive creates a property of the template that allows the end user to choose an XML file at runtime. The XmlProperty directive has six possible attributes:
Name attribute is used as the name of the property when it is displayed on the template's property sheet in CodeSmith. This is also the variable name that is used to store the value of the property within the template.
Schema attribute specifies an XSD schema to be used to parse the XML file chosen by the user at runtime. This attribute is optional, but I strongly recommend that you supply a schema, because this enables strong typing and IntelliSense within the template.
Default attribute is used to set the default value for this property.
Category attribute specifies what category this property should appear under in the CodeSmith Explorer property sheet.
Description attribute supplies descriptive text to be displayed at the bottom of the property sheet when this property is selected.
Optional attribute specifies whether or not this property is optional. From XML to HTML
<?xml version="1.0" encoding="UTF-8"?>
<TestReport xmlns="http://www.example.com/testing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ProjectName>Inventory Project</ProjectName>
<TestDate>2005-08-05</TestDate>
<Tests>
<Test TestNumber="1" TestName="Basic data
entry" Passed="1"/>
<Test TestNumber="2" TestName="Advanced data
entry" Passed="0"/>
<Test TestNumber="3" TestName="Basic reporting"
Passed="1"/>
<Test TestNumber="4" TestName="Advanced
reporting" Passed="1"/>
<Test TestNumber="5" TestName="Inventory
reconciliation" Passed="0"/>
</Tests>
</TestReport>
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.example.com/testing"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.example.com/testing"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="TestReport">
<xs:complexType>
<xs:sequence>
<xs:element name="ProjectName"
type="xs:string"/>
<xs:element name="TestDate" type="xs:date"/>
<xs:element name="Tests">
<xs:complexType>
<xs:sequence>
<xs:element name="Test"
maxOccurs="unbounded"> <xs:complexType>
<xs:attribute name="TestNumber"
type="xs:integer" use="required"/>
<xs:attribute name="TestName"
type="xs:string" use="required"/>
<xs:attribute name="Passed"
type="xs:boolean"
use="required"/> </xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
XmlProperty directive) to provide IntelliSense-style help in the IDE. This makes it very easy to get the proper element and attribute names from the XML file into the template.

Click here for a larger image.
Generating the Report
<%= %> 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.

Click here for a larger image.
<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>
Working Smarter is the Key
About the Author