Recipe 14.23. Creating an XML Document


Problem

You need to build an XML file that contains important configuration or processing data, and you aren't excited about doing all the string concatenation yourself.

Solution

Sample code folder: Chapter 14\GenerateXMLContent

Use the XML document creation tools in the System.XML namespace to generate the XML. This namespace includes a few different ways of building XML content. One of the simplest methods is to fill in a System.Xml.XmlDocument object by building it with distinct System.Xml.XmlElement objects.

Discussion

This recipe's sample code builds a simple program that outputs a list of email recipients in XML format. It groups recipients by the desired email format, either HTML or plain text. Here is a sample of the generated XML content:

 <?xml version="1.0"?> <emailData>   <emailRecipients mailType="HTML">     <recipient>       <name>John Smith</name>       <address>jsmith@fakeemail.com</address>     </recipient>     <recipient>       <name>Jane Jones</name>       <address>jane.jones@dontmailme.com</address>     </recipient>   </emailRecipients>   <emailRecipients mailType="Text">     <recipient>       <name>Brenda Wong</name>       <address>puppyfriend@ilikedogs.net</address>     </recipient>   </emailRecipients> </emailData> 

Create a new Windows Forms application, and add the following controls to Form1:

  • A ComboBox control named EmailType. Set its DropDownStyle property to DropDownList.

  • A TextBox control named RecipientName.

  • A TextBox control named RecipientAddress.

  • A ListBox control named AllRecipients.

  • A Button control named AddEmail. Set its Text property to Add.

  • A Button control named DeleteEmail. Set its Text property to Delete.

  • A TextBox control named XMLFile.

  • A Button control named SaveFile. Set its Text property to Save.

Add informational labels if desired, and arrange the controls so that Form1 looks like the form in Figure 14-19.

Figure 14-19. Controls for the XML-generation sample


Now add the following source code to Form1's class template:

 Public Class RecipientData    ' ----- A simple class to hold the basics of an address.    Public EmailType As String    Public EmailName As String    Public EmailAddress As String    Public Sub New(ByVal newType As String, _          ByVal newName As String, ByVal newAddress As String)       ' ----- Constructor to build the new record.       EmailType = newType       EmailName = newName       EmailAddress = newAddress    End Sub    Public Overrides Function ToString( ) As String       ' ----- Display a nicely formatted address.       Return EmailName & " <" & EmailAddress & ">"    End Function End Class Private Sub Form1_Load(ByVal sender As System.Object, _       ByVal e As System.EventArgs) Handles MyBase.Load    ' ----- Add the types of email content.    EmailType.Items.Add("HTML")    EmailType.Items.Add("Text")    EmailType.SelectedIndex = 0 End Sub Private Sub DeleteEmail_Click(ByVal sender As System.Object, _       ByVal e As System.EventArgs) Handles DeleteEmail.Click    ' ----- Remove the selected email address.    If (AllRecipients.SelectedIndex <> ListBox.NoMatches) Then _       AllRecipients.Items.Remove(AllRecipients.SelectedItem) End Sub Private Sub AddEmail_Click(ByVal sender As System.Object, _       ByVal e As System.EventArgs) Handles AddEmail.Click    ' ----- Add an email recipient. Check for missing data.    If (RecipientName.Text.Trim = "") Then       MsgBox("Please supply a recipient name.")       Return    End If    If (RecipientAddress.Text.Trim = "") Then       MsgBox("Please supply a recipient address.")       Return    End If    ' ----- Add this recipient to the list.    AllRecipients.Items.Add(New RecipientData( _       EmailType.Text, RecipientName.Text, _       RecipientAddress.Text))    ' ----- Get ready for a new entry.    RecipientName.Clear( )    RecipientAddress.Clear( )    RecipientName.Focus( ) End Sub Private Sub SaveFile_Click(ByVal sender As System.Object, _       ByVal e As System.EventArgs) Handles SaveFile.Click    ' ----- Save the   XML content.    Dim emailSet As Xml.XmlDocument    Dim emailDeclare As   Xml.XmlDeclaration    Dim emailRoot As Xml.XmlElement    Dim emailGroup As Xml.XmlElement    Dim emailRecipient As Xml.XmlElement    Dim emailDetail As Xml.XmlElement    Dim counter As Integer    Dim useType As String    Dim scanEmail As Object    Dim oneEmail As RecipientData    ' ----- Check for missing data.    If (AllRecipients.Items.Count = 0) Then       MsgBox("Please enter at least one recipient.")       Return    End If    If (XMLFile.Text.Trim = "") Then       MsgBox("Please specify the output file.")       Return    End If    ' ----- Warn if the file exists.    If (My.Computer.FileSystem.FileExists(XMLFile.Text)) Then       If (MsgBox("The file exists. Overwrite?", _          MsgBoxStyle.YesNo Or MsgBoxStyle.Question) <> _          MsgBoxResult.Yes) Then Return       Try          Kill(XMLFile.Text)       Catch ex As Exception          MsgBox("Could not replace the file. " & ex.Message)          Return       End Try    End If    ' ----- Start the XML document with an XML declaration.    emailSet = New Xml.XmlDocument    emailDeclare = emailSet.CreateXmlDeclaration("1.0", _       Nothing, String.Empty)    emailSet.InsertBefore(emailDeclare, _       emailSet.DocumentElement)    ' ----- Add in the root <emailData> element.    emailRoot = emailSet.CreateElement("emailData")    emailSet.InsertAfter(emailRoot, emailDeclare)    ' ----- Scan through the recipients, once for each type.    For counter = 0 To EmailType.Items.Count - 1       ' ----- Prepare for this pass.       useType = EmailType.Items(counter)       emailGroup = Nothing       For Each scanEmail In AllRecipients.Items          oneEmail = CType(scanEmail, RecipientData)          If (oneEmail.EmailType = useType) Then             ' ----- Found a recipient in this group.             '       Add the group if needed.             If (emailGroup Is Nothing) Then                emailGroup = emailSet.  CreateElement( _                   "emailRecipients")                emailGroup.SetAttribute("mailType", useType)                emailRoot.AppendChild(emailGroup)             End If             ' ----- Build the new output entry.             emailRecipient = emailSet.CreateElement( _                "recipient")             emailGroup.AppendChild(emailRecipient)             emailDetail = emailSet.CreateElement("name")             emailDetail.InnerText = oneEmail.EmailName             emailRecipient.AppendChild(emailDetail)             emailDetail = emailSet.CreateElement("address")             emailDetail.InnerText = oneEmail.EmailAddress             emailRecipient.AppendChild(emailDetail)          End If       Next scanEmail    Next counter    ' ----- Write out the   XML content.    Try       emailSet.Save(XMLFile.Text)       MsgBox("XML content saved.")    Catch ex As Exception       MsgBox("Could not write the XML content. " & _          ex.Message)    End Try End Sub 

To use the program, select an email type (HTML or Text) from the Type drop-down list, enter in a recipient name and email address in the two text fields next to the drop-down, and then click the Add button to add the recipient to the list. Repeat as needed. When you have added enough recipients, supply an output filename in the XML File field, and then click the Save button.

Most of this recipe's sample code lets you build the list of email recipients in a ListBox control. The embedded RecipientData class helps organize the content stored in each ListBox item.

The real XML work happens in the Click event handler for the SaveFile button. After performing some quick verification, the method creates a new XmlDocument to store the new XML content. For each node in the output, it then creates XmlElement objects using the XmlDocument.CreateElement() method. This method generates a generic XML element, representing a standard XML tag. It adds attributes to the element via the XmlElement.SetAttribute() method. These completed elements are then inserted into the existing XmlDocument structure relative to other existing nodes.

The various uses of the InsertBefore(), InsertAfter(), and AppendChild() methods in the sample code show how you can position elements as you need them.

Besides CreateElement(), XmlDocument includes other Create… methods that generate a variety of XML-specific content entities. For example, the CreateXmlDeclaration() method is used in the sample code to generate the <?xml version="1.0"?> tag at the start of the document:

 emailDeclare = emailSet.CreateXmlDeclaration("1.0", _    Nothing, String.Empty) 

Once elements have been added to the XmlDocument, you can traverse them using any of the supported XML tools, such as XPath.

See Also

Recipes 14.22 and 14.24 discuss other methods of working with XML content.




Visual Basic 2005 Cookbook(c) Solutions for VB 2005 Programmers
Visual Basic 2005 Cookbook: Solutions for VB 2005 Programmers (Cookbooks (OReilly))
ISBN: 0596101775
EAN: 2147483647
Year: 2006
Pages: 400

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net