Writing Element and Attribute Content


Writing elements and attributes piece by piece requires you to write the content separately from the start and end tags. Up to this point, this chapter has glossed over which methods are available for writing this content. This section will investigate these methods in more detail.

The XmlTextWriter provides the WriteString method to assist you in writing string data as content. To ensure that the resulting XML is still well- formed , the WriteString method will perform the following tasks before writing the string:

  • The characters & , < , and > are replaced by &amp; , &lt; , and &gt; , respectively.

  • Character values in the range 0x 0x1F are replaced by numeric character entries. White space characters with this range are not converted.

  • If WriteString is called to write the value of an attribute, double and single quotes are replaced by &quot; and &apos; , respectively.

It is important to note that the WriteString method considers null and the empty string to be equal. If the WriteString receives a null or String.Empty , no text content will be written out. For attributes, the value will be "" .

The code in Listing 10.28 demonstrates WriteString used to build an element and its attribute.

Listing 10.28
 C# public static void Main() {    XmlTextWriter writer =      new XmlTextWriter("writestring.xml", Encoding.UTF8);    writer.Formatting = Formatting.Indented;    writer.WriteStartElement("root");    writer.WriteStartElement("Element");    writer.WriteStartAttribute("att1", "");    writer.WriteString("< > & \" '");    writer.WriteEndAttribute();    writer.WriteStartAttribute("att2", "");    writer.WriteString(null);    writer.WriteEndAttribute();    writer.WriteString("This is text < > &");    writer.WriteEndElement();    writer.WriteStartElement("Empty");    writer.WriteString(null);    writer.WriteEndElement(); :    writer.WriteEndElement();    writer.Close(); } VB sub Main()    Dim writer As      New XmlTextWriter("writestring.xml", Encoding.UTF8)    writer.Formatting = Formatting.Indented    writer.WriteStartElement("root")    writer.WriteStartElement("Element")    writer.WriteStartAttribute("att1", "")    writer.WriteString("< > & \" '")    writer.WriteEndAttribute()    writer.WriteStartAttribute("att2", "")    writer.WriteString(nothing)    writer.WriteEndAttribute()    writer.WriteString("This is text < > &")    writer.WriteEndElement()    writer.WriteStartElement("Empty")    writer.WriteString(nothing)    writer.WriteEndElement()    writer.WriteEndElement()    writer.Close() End Sub Output <root>   <Element att1="&lt; &gt; &amp; &quot; '" att2="">     This is text &lt; &gt; &amp;   </Element>   <Empty /> </root> 

If you have a large amount of text to write to the XmlTextWriter , it may be inefficient to load all of the text into one string and then write the string using WriteString . It would be more efficient to write a chunk of the text to a buffer and then write the buffer to the XmlTextWriter . Well, the XmlTextWriter supports this type of buffered writing with WriteChars .

The WriteChars method writes the content one buffer at a time. This method takes three arguments. The first argument is the array of characters to be written; an ArgumentNullException will be raised if you pass null as this parameter. The second argument is the position in the buffer indicating the start of the text to write. This parameter must not be less than zero. If it is, an ArgumentOutOfRangeException will be raised. The third argument is the number of characters to write; an ArgumentOutOfRangeException will again be thrown if this parameter is less than zero. Listing 10.29 demonstrates WriteChars .

Listing 10.29
 C# char[] buffer = new char[64]; int bytesRead; while(0 != (bytesRead = reader.Read(buffer, 0, 64))) {   writer.WriteChars(buffer, 0, bytesRead); } writer.WriteEndElement(); writer.Close(); VB Dim buffer(64) As Char Dim bytesRead As Integer while(Not 0 = (bytesRead = reader.Read(buffer, 0, 64)))   writer.WriteChars(buffer, 0, bytesRead) End While writer.WriteEndElement() writer.Close() 

This method is ideal for writing large amounts of data to the XmlTextWriter . This method uses less memory because the input is buffered. Performance is also increased because string manipulation, which can often cause unnecessary garbage, is bypassed by using the character array. This method is ideal for.NET Compact Framework, given the resource-constrained devices your code will be operating on.

Writing binary-encoded data is possible using the WriteBase64 and WriteBinHex methods. The methods are very similar except for the obvious fact that they use different encoding algorithms. The algorithms take the same number of arguments, return the same return value ( void ), and throw the same exceptions in similar situations.

The methods take three arguments. The first argument is a byte array that contains the data to encode. Both methods will raise an ArgumentNullException if the byte buffer is null. The second attribute is the index into the buffer that indicates the start index of the bytes to write. The third argument is a number of bytes to write to the stream. Both methods will throw ArgumentOutOfRangeException s if either the index or the count of bytes is less than zero. An ArgumentException is also thrown if the byte array length minus the index is less than the number of bytes to write. Listing 10.30 demonstrates how to write binary encoded data with the XmlTextWriter.

WRITING SURROGATE CHARACTERS WITH WriteChars

The WriteChars method requires special care when writing surrogate characters. If you split a surrogate character across multiple buffers, a System.ArgumentException will be thrown while writing the first half of the surrogate pair. When this exception is thrown, the last character written will be the character right before the first half of the surrogate pair. Therefore, after catching the exception, create a new buffer that includes the first half of the surrogate pair that caused the exception, followed by the second half of the surrogate pair. Then call WriteChars again, using the new buffer. This will ensure that the surrogate character is written to the stream correctly. The code that follows illustrates this concept:

 
 C# static void Main() {   XmlTextWriter writer =     new XmlTextWriter("surrogate.xml", Encoding.UTF8);   char [] charArray = new char[4];   char low = Convert.ToChar(0xDC00);   char high = Convert.ToChar(0xD800);   writer.WriteStartElement("DocumentElement");   charArray[0] = 'w';   charArray[1] = 'x';   charArray[2] = 'y';   charArray[3] = high;   try   {     writer. WriteChars(charArray, 0, charArray.Length);   }   catch (ArgumentException ex)   {     charArray[0] = high;     charArray[1] = low;     charArray[2] = 'z';     writer.WriteChars(charArray, 0, 3);   }   writer.WriteEndElement();   writer.Close(); } 

Listing 10.30
 C# public void WriteBinaryData(string filename) {   byte[] buffer = new byte[64];   int bytesRead = 0;   BinaryReader binReader =     new BinaryReader(new FileStream(filename, FileMode.Open));   XmlTextWriter xmlWriter =     new XmlTextWriter("out.xml", Encoding.UTF8);   xmlWriter.WriteStartElement("Encoded_ File");   while(0 != (bytesRead = binReader.Read(buffer, 0, 64)))   {     xmlWriter.WriteBase64(buffer, 0, bytesRead);   }   xmlWriter.WriteEndElement();   xmlWriter.Close(); } VB sub WriteBinaryData(filename as String)   Dim buffer(64) As Char   Dim bytesRead As integer   Dim BinaryReader As     New BinaryReader(New FileStream(filename, FileMode.Open)        Dim xmlWriter As     New XmlTextWriter("out.xml", Encoding.UTF8)   xmlWriter.WriteStartElement("Encoded_File")   while(Not 0 = (bytesRead = binReader.Read(buffer, 0, 64)))     xmlWriter.WriteBase64(buffer, 0, bytesRead)   End While   xmlWriter.WriteEndElement()   xmlWriter.Close() End Sub 

These methods are ideal for writing any binary data to the XML stream. In fact, they are the only valid ways to write binary data to an XML stream using XmlTextWriter . A few examples of situations where you should use WriteBase64 and WriteBinHex include embedding image data and sound bites. You should understand that embedding binary data in an XML stream will almost always result in a large XML stream, so embed wisely.



Microsoft.NET Compact Framework Kick Start
Microsoft .NET Compact Framework Kick Start
ISBN: 0672325705
EAN: 2147483647
Year: 2003
Pages: 206

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