The XMLTextWriter class is obviously not difficult to create an XML document in this section. Over the years, developers have created an XML document by outputting the string in the cache in the way in which the cache is output to the file by connecting some strings in the cache. But in this way, the way to create an XML document is only valid when you guarantee that there is no fine error in the string. .NET Framework provides a better way to create an XML document with XMLWRITER. The XML Writer class outputs XML data in the forward-only mode to flow or files. More importantly, XML Writer guarantees that all XML data is in accordance with W3C XML 1.0 recommended specification, you don't even have to worry about writing a tag, because XML Writer will help you. XMLWRITER is an abstract base class for all XML Writer. .NET Framework only provides a unique Writer class ---- XMLTextWriter class. Let's take a look at the difference between XML Writers and the old Writers. The following code saves an array of String type: StringBuilder SB = New StringBuilder (""); sb.append ("
Figure 6 Serializing a string array
void CreateXmlFileUsingWriters (String [] theArray, string filename) {// Open the XML writer (with the default character set) XmlTextWriter xmlw = new XmlTextWriter (filename, null); xmlw.Formatting = Formatting.Indented;
xmlw.WriteStartDocument (); xmlw.WriteStartElement ( "array"); foreach (string s in theArray) {xmlw.WriteStartElement ( "element"); xmlw.WriteAttributeString ( "value", s); xmlw.WriteEndElement ();} XMLW.WriteEndDocument ();
// close the Writer XMLW.Close ();} However, XML Writer is not a magician - it cannot fix the input error. XML Writer does not check if the element name and the property name are valid, nor to ensure that any Unicode character set is suitable for the current architecture coding set. As mentioned above, in order to avoid output errors, it is necessary to prevent non-XML characters. But Writer did not provide this method. In addition, when an attribute node is created, WRITER does not verify that the name of the property node is the same as the name of the existing element node. Finally, the XMLWRITER class is not a verified Writer class, nor does it guarantee whether the output complies with SCHEMA or DTD. The Writer class with verification in .NET Framework is not available yet. But in my "Applied XML Programming for Microsoft .NET (Microsoft Press®, 2002)" book, I wrote a writable Writer component. You can download the source code from the following URL: http://www.microsoft.com/mspress/books/6235.asp. Figure 7 lists some status values of XML Writer (state). These values are derived from the WriteState enumeration class. When you create a Writer, its initial state is start, indicating that you will configure the object, actually Writer doesn't start. The next state is ProLog, which is set when you call the WritestartDocument method to start working. Then, the conversion of the state depends on your write documentation and the content of the document. ProLog State has been reserved until you add a non-element node, such as comment elements, processing instructions, and document types. When the first node is written after the root node is written, the state changes to ELEMENT. When you call the WritersTARTRIBUTE method, the status is converted to Attribute instead of converting the WRITEATRIBUTESTRING method write property to this state. If so, the status should be Element. When you write a closed tag (>), the status will be converted to Content. When you write a document, call the WriteEndDocument method, the status will return to start until you start writing another document or turn the Writer. Figure 7 States for XML Writerstate
Description
Attribute
The Writer Enters this state when an attribute is being written
Closed
The Close Method Has Been Called and The Writer Is No Longer Available for Writing Operations
Content
The Writer Enters this State When THE Content of a Node Is Being Written
ELEMENT
The Writer Enters this State When An Element Start Tag Is Being Written
PROLOG
The Writer Is Writing The Prolog of A Well-Formed XML 1.0 Document
Start
The Writer Is in An Initial State, AWAITI for a Write Call To Be Issued
Writer puts the output text within a buffer internally. In general, the buffer will be refreshed or cleared. When Writer is turned off, XML text should be written. You can clear the buffer by calling the Flush method, write the current content into the stream (exposing the BaseStream property), then release the memory, Writer remains open state, can continue operating. Note that although the partial document content is written, it is not possible to handle the document before the Writer is not closed. It can be used to write attribute nodes in two ways. The first method is to create a new attribute node to update the status of the Writer with the WriteStartatribute method. Then use the WRITESTRING method to set the attribute value. After writing, the node is ended with the WriteEndelement method. Alternatively, you can also create a new property node with WriteAttributeString method. When Writerr's status is ELEMENT, WriterattributeString starts working, it creates an attribute separately. Similarly, WriteStartElement methods write nodes start tabs (<), then you can set the properties of the node and the text content of the node. The closed tag of the element node is "/>". If you want to write and clock the tag, you can use the WriteFullendElement method to write. A sensitive tag character includes sensitive tag characters should be avoided, such as less than numbers (<). Writing the stream with the WriteraW method does not be parsed, we can use it to write a special string for the XML document. The following two lines of code, the first line output "& lt", the second line output "<":
Writer.writestring ("<");
Writer.writeraw ("<"); read and write flow
Interestingly, Reader and Writer class provide methods of read and write data streams based on Base64 and BinHex encoding. The function of the WriteBase64 and WritebinHex methods is a subtle difference with other write methods. They are all streaming, the functions of these two methods are like a BYTE array rather than a string. The following code first converts a String into a Byte array and writes them into a base64 encoded stream. Encoding class's Gettes static method completes the transition task:
Writer.writebase64 (
Encoding.unicode.getbytes (buf),
0, BUF.LENGTH * 2);
Figure 8 The code demonstrates the XML stream that converts a String data to the Base64 encoded. Figure 9 is the result of the output.
Figure 8 persists a string array as base64
Using system;
Using system.text;
Using system.io;
USING SYSTEM.XML;
Class mybase64array
{
Public static void main (string [] args)
{
String OutputFileName = "TEST64.XML";
IF (args.length> 0)
OutputFileName = args [0]; // file name
/ / Convert array to XML
String [] THEARRAY = {"Rome", "New York", "Sydney", "stockholm",
Paris "};
CreateOutput (THEARRAY, OUTPUTFILENAME); RETURN
}
Private static void createoutput (String [] THEARRAY, STRING FileName)
{
// Open XML Writer
XmlTextWriter XMLW = New XMLTextWriter (filename, null);
/ / The child element is set indent according to Indentation and IndentChar. This option is only indentation
XMLW.MMATTING = formatting.indented;
// Wait-write version of XML declaration "1.0"
XMLW.writestartDocument ();
// Write out the comment containing the specified text .
XMLW.WriteComment ("Array to Base64 XML);
/ / Start writing Array node
XMLW.WriteStartElement ("array");
// Write an attribute with the specified prefix, local name, namespace URI and value
XMLW.WRITEATTRIBUTESTRING ("XMLns", "X", NULL, "DINOE: MSDN-MAG");
// Cycle the child's child node
FOREACH (String S in Thearray)
{
/ / Write the specified start tag and associate it with a given namespace and prefix
XMLW.WriteStartElement ("X", "Element", NULL;
/ / Convert S to the Byte [] array, and encode the BYTE [] array to Base64 and write the result text, the number of bytes to be written is 2 times the total length of String, and the number of bytes occupying 2 is 2 byte.
XMLW.WriteBase64 (Encoding.unicode.getbytes (s), 0, s.length * 2);
// Turn off the child node
XMLW.WriteEndelement ();
}
// Close the root node, only two levels
XMLW.WriteEndDocument ();
// Close Writer
XMLW.Close ();
// read the content written
XMLTextReader Reader = New XMLTextReader (FileName);
While (Reader.Read ())
{
/ / Get the node named ELEMENT
IF (reader.localname == "element")
{
BYTE [] bytes = new byte [1000];
INT N = Reader.Readbase64 (bytes, 0, 1000);
String buf = encoding.unicode.getstring (bytes);
Console.writeline (buf.substring (0, n));
}
}
Reader.Close ();
}
}