XML Property Examples

XML Property With a Schema

Here's an example of using the XmlProperty directive with a schema. Consider first this XSD file, which defines a simple purchase order structure:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace=http://www.codesmithtools.com/PO
     xmlns:xs=http://www.w3.org/2001/XMLSchema
     xmlns=http://www.codesmithtools.com/PO
     elementFormDefault="qualified" attributeFormDefault="unqualified">
   <xs:element name="PurchaseOrder">
     <xs:complexType>
       <xs:sequence>
         <xs:element name="PONumber" type="xs:string"/>
         <xs:element name="CustomerName" type="xs:string"/>
         <xs:element name="CustomerCity" type="xs:string"/>
         <xs:element name="CustomerState" type="xs:string"/>
         <xs:element name="Items">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Item" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:attribute name="ItemNumber" type="xs:string" use="required"/>
                  <xs:attribute name="Quantity" type="xs:integer" use="required"/>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
         </xs:element>
       </xs:sequence>
     </xs:complexType>
   </xs:element>
</xs:schema>

Using this schema file, you can define an XML property that accepts purchase order files at runtime for its metadata:

<%@ CodeTemplate Language="C#" TargetLanguage="Text" Description="Create packing list from XML PO." %>
<%@ XmlProperty Name="PurchaseOrder" Schema="PO.xsd" Optional="False" Category="Data" Description="Purchase Order to generate packing list for." %>
Packing List
ref: PO#<%= PurchaseOrder.PONumber %>
Ship To:
<%= PurchaseOrder.CustomerName %>
<%= PurchaseOrder.CustomerCity  %>, <%= PurchaseOrder.CustomerState %>
Contents:
<% for (int i = 0; i < PurchaseOrder.Items.Count; i++) { %>
<%= PurchaseOrder.Items[i].ItemNumber %>, Quantity <%= PurchaseOrder.Items[i].Quantity %>
<% } %>

At run time, the PurchaseOrder 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:

Selecting an appropriate XML file generates the packing list. For example, the user might choose this XML file:

<?xml version="1.0" encoding="UTF-8"?>
<PurchaseOrder xmlns=http://www.codesmithtools.com/PO
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <PONumber>5271</PONumber>
   <CustomerName>John Nelson</CustomerName>
   <CustomerCity>Gamonetta</CustomerCity>
   <CustomerState>MS</CustomerState>
   <Items>
     <Item ItemNumber="HM85" Quantity="12"/>
     <Item ItemNumber="JR82" Quantity="4"/>
     <Item ItemNumber="PR43" Quantity="6"/>
   </Items>
</PurchaseOrder>

With this resulting generated packing list:

Packing List
ref: PO#5271
Ship To:
John Nelson
Gamonetta, MS
Contents:
HM85, Quantity 12
JR82, Quantity 4
PR43, Quantity 6
XML Property Without a Schema

Here's an example of using the XmlProperty directive without a schema. Here's a template that can accept any XML file at runtime:

<%@ CodeTemplate Language="VB" TargetLanguage="Text" Description="List top-level nodes in an XML file." %>
<%@ XmlProperty Name="TargetFile" Optional="False" Category="Data" Description="XML file to iterate." %>
<%@ Assembly Name="System.Xml" %>
<%@ Import Namespace="System.Xml" %>
Top-level nodes:
<% Dim currNode as XmlNode
currNode = TargetFile.DocumentElement.FirstChild
Do Until currNode Is Nothing%>
   <%= currNode.InnerXml %>
<% currNode = currNode.NextSibling()
Loop %>

This template doesn't define a schema for the TargetFile property, so that property is presented to the template as an XmlDocument object. Thus, it can be processed with the standard XML DOM methods and properties such as FirstChild and NextSibling. In this case, the template simply loops through the top-level nodes of the document and copies them to the output. For example, if you choose this document as the TargetFile:

<?xml version="1.0" encoding="UTF-8"?>
<Books>
   <Book>UML 2.0 In a Nutshell</Book>
   <Book>The Best Software Writing</Book>
   <Book>Coder to Developer</Book>
   <Book>Code Complete</Book>
</Books>

Then the template's output looks like this:

Top-level nodes:
 UML 2.0 In a Nutshell
 The Best Software Writing
 Coder to Developer
 Code Complete