XML property examples

XML property with a schema

This example uses the XmlProperty directive with a schema. First, this XSD file defines a simple purchase order:

<?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>

With this schema, you can declare an XML property that accepts purchase order files as its metadata. The template code uses the elements and attributes of the purchase order as typed properties:

<%@ 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 %>
<% } %>

When the user runs the template, the PurchaseOrder property shows a builder button (...) in the property grid. Clicking it opens a file dialog where the user chooses an XML file to use as the metadata. For example, the user might choose this 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>

The template then generates this 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

This Visual Basic template uses the XmlProperty directive without a schema, so it accepts any XML file:

<%@ 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 %>

Because there's no schema, the TargetFile property is an XmlDocument, and you work with it through the standard XML DOM members such as FirstChild and NextSibling. This template loops through the top-level nodes of the document and copies them to the output. 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>

The output is:

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