ProblemYou 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. SolutionSample 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. DiscussionThis 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:
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 sampleNow 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 AlsoRecipes 14.22 and 14.24 discuss other methods of working with XML content. |