XmlTextWriterXmlTextWriter is derived from the XmlWriter class. XmlWriter is the abstract class that defines the basic functionality required to produce document streams conforming to the W3C's XML recommendations. XmlWriter completely shields applications from the complexities of producing XML document streams by enabling them to work with a well-organized API. Producing a document with XmlWriter is very similar to producing documents via SAX. Currently there is one implementation of XmlWriter: XmlTextWriter. These implementations are just like reader versions, only they work in the opposite directions. XmlWriter makes it possible to write out all standard constructs such as elements, attributes, and processing instructions. It does this using the corresponding methods. Some of these methods include WriteStartDocument(), WriteStartElement(), and WriteProcessingInstruction(). XmlWriter also provides methods for writing out typed elements and attributes through the WriteElement() and WriteAttribute() methods. The source code for this entire part of the application can be seen in Listing 9.4. This part of the application can be seen running in Figure 9.2. You need to notice that the first thing I do is create an XmlTextWriter object. I pass the file name as an argument to the constructor. This actually creates the XML file before any data is written. I also set the formatting to be indented. If I don't do this, the entire XML file will be one long line with no carriage returns; it then becomes hard to read in any kind of text editor. If your file needs to be opened up or edited with anything besides XmlTextReader, you need to be sure you set the Formatting property to Formatting.Indented. Figure 9.2. This Page Shows How to Use XmlWriter to Create and Write to an XML File.The first thing you need to do to create an XML file is to call the WriteStart() document method. This prepares the XmlTextWriter for creating a new document. I then call the WriteComment() method, but this is optional, and you may not need to do this in your particular application. Another optional method I call is the WriteProcessing() instruction. To create the elements and write the data into these elements, I use a combination of the WriteStartElement() method, the WriteString() method, and the WriteEndElement() method. These methods create the elements, write the data to them, and then close them up. Because I have five elements, I made this set of calls five times: once for the name, once for the address, once for the city, once for the state, and once for the Zip code. The last thing I had to do was call the WriteEndDocument() method. This closed off the document internally and prepared it for writing to disk. When I finally called the Close() method, all the XML data that was contained in the XmlTextWriter class was saved out to disk. Listing 9.4 The C# Source Code That Demonstrates a Simple Example Using XML Text ReaderC# public void UseTextReader_Click(System.Object sender, System.EventArgs e) { try { XmlTextWriter Writer = new XmlTextWriter( Request.MapPath( "SimpleInfo.xml" ), System.Text.Encoding.Default ); Writer.Formatting = Formatting.Indented; Writer.WriteStartDocument(); Writer.WriteComment( "Addison-Wesley is a great publisher!" ); Writer.WriteProcessingInstruction( "Read", "Information" ); Writer.WriteStartElement( "i", "Info", "urn:Info" ); Writer.WriteStartElement( "Name", "" ); Writer.WriteString( TextBox1.Text ); Writer.WriteEndElement(); Writer.WriteStartElement( "Address", "" ); Writer.WriteString( TextBox2.Text ); Writer.WriteEndElement(); Writer.WriteStartElement( "City", "" ); Writer.WriteString( TextBox3.Text ); Writer.WriteEndElement(); Writer.WriteStartElement( "State", "" ); Writer.WriteString( TextBox4.Text ); Writer.WriteEndElement(); Writer.WriteStartElement( "Zip", "" ); Writer.WriteString( TextBox5.Text ); Writer.WriteEndElement(); Writer.WriteEndDocument(); Writer.Close(); Label1.Text = "Done!"; } catch( Exception ex ) { Label1.Text = ex.Message.ToString(); } } VB Private Sub UseTextReader_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click Try Dim Writer As New _ XmlTextWriter(Request.MapPath("SimpleInfo.xml"), System.Text.Encoding.Default) Writer.Formatting = Formatting.Indented Writer.WriteStartDocument() Writer.WriteComment("Addison-Wesley is a great publisher ") Writer.WriteProcessingInstruction("Read", "Information") Writer.WriteStartElement("i", "Info", "urn:Info") Writer.WriteStartElement("Name", "") Writer.WriteString(TextBox1.Text) Writer.WriteEndElement() Writer.WriteStartElement("Address", "") Writer.WriteString(TextBox2.Text) Writer.WriteEndElement() Writer.WriteStartElement("City", "") Writer.WriteString(TextBox3.Text) Writer.WriteEndElement(); Writer.WriteStartElement("State", "") Writer.WriteString(TextBox4.Text) Writer.WriteEndElement() Writer.WriteStartElement("Zip", "") Writer.WriteString(TextBox5.Text) Writer.WriteEndElement() Writer.WriteEndDocument() Writer.Close() Label1.Text = "Done!" Catch ex As Exception Label1.Text = ex.MessageToString() End Try End Sub This example also includes a button that enables you to view the raw XML text file. The method I created that does this doesn't use any of the XML classes. It simply opens the file, reads in the lines, and displays them in a label. You can see this code in Listing 9.5. In this code, I created a stream reader by calling the file OpenText() method, reading through the file one line at a time, and then closing it. Listing 9.5 This Code Reads In the XML File and Displays It in Raw Format.C# public void Display_Click(System.Object sender, System.EventArgs e) { Label2.Text = "<pre>"; try { StreamReader reader = File.OpenText(Request.MapPath("SimpleInfo.xml")); while( reader.Peek() != -1 ) { Label2.Text += ( Server.HtmlEncode( reader.ReadLine() ) + "<br>\r\n" ); } reader.Close(); Label2.Text += "</pre>"; } catch( Exception ex ) { Label2.Text = ex.Message.ToString(); } } VB Private Sub Display_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click Label2.Text = "" Try StreamReader reader = _ File.OpenText(Request.MapPath("SimpleInfo.xml")) While reader.Peek() <> -1 Label2.Text += ( Server.HtmlEncode( reader.ReadLine() ) + _ "<br>\r\n" ); End While reader.Close() Catch ex As Exception Label2.Text = ex.Message.ToString() End Try End Sub The XML data that is written to disk is a very simple file. This file can be seen in Listing 9.6. Listing 9.6 This Is the Simple XML File That Was Saved Out from the Code in Listing 9.5.<?xml version="1.0" encoding="Windows-1252"?> <!--Special Edition: Using ASP.NET is a great book!--> <?Read Information?> <i:Info xmlns:i="urn:Info"> <Name>Rick</Name> <Address>123</Address> <City>5t</City> <State>ef</State> <Zip>asdf</Zip> </i:Info> I have created an example on www.ASPNET-Solutions.com. The example allows a user to type in a query. It then searches through XML files to try to find a match or matches for the user's query. You can see this example running in Figure 9.3. Figure 9.3. You Can Perform Queries in an XML File with the DocumentNavigator Class.The source code for this example can be seen in Listing 9.7. To accomplish the query, I first created an XmlDocument object. I then loaded the document using the Load() method. And as you can see by the source code listing, the Load() method takes a single argument, which is a string containing the file name. You may want to notice that once again I used the Request.MapPath() method to provide a fully qualified file name to the method. After loading the XML file, I created a DocumentNavigator object. Then I used the Select() method to do the query. The Select() method takes a single argument, which is the string containing the query that must be used. I then looped through by using the MoveToNextSelected() method and displayed each match for the query found. Bear in mind that the XML document contains ice cream, so to have a successful query, the user needs to enter something such as chocolate or vanilla. Listing 9.7 This C# Code Performs a Query on the XML Data.C# public void Match_Click(System.Object sender, System.EventArgs e) { try { XmlDocument doc = new XmlDocument(); doc.Load(Request.MapPath("IceCream.xml")); DocumentNavigator nav = new DocumentNavigator(doc); nav.Select(TextBox1.Text); bool bFound = false; Label1.Text = ""; while( nav.MoveToNextSelected()) { Label1.Text += ( nav.InnerText + "<br>\n\r" ); bFound = true; } if( !bFound ) { Label1.Text = "No matches found!"; } } catch( Exception ex ) { Label1.Text = ex.Message.ToString(); } } VB Public Sub Match_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Try XmlDocument doc = new XmlDocument() doc.Load(Request.MapPath("IceCream.xml")) Dim nav As New DocumentNavigator(doc) nav.Select(TextBox1.Text) Dim bFound as bool = False Label1.Text = "" While nav.MoveToNextSelected() Label1.Text += ( nav.InnerText + "<br>\n\r" ) bFound = True End While If not bFound Then Label1.Text = "No matches found!" End If Catch ex As Exception Label1.Text = ex.Message.ToString() End Try End Sub The XmlDocument and XmlNavigator classes provide you with a rich and powerful capability to perform queries on XML documents. They are easy to use and you will quickly be using them to add powerful functionality to your applications. |