Easily process XML data in the. NET Framework (IV)

Source: Internet
Author: User
Tags foreach array base64 character set net return string valid
xml| Data xmltextwriter Class

It is obviously not difficult to create an XML document using the methods in this section. For years, developers have created XML documents in a way that caches strings, connects them, and then prints the strings in the cache to a file. But the way to create an XML document in this way is only valid if you guarantee that there are no small errors in the string. The. NET framework provides a better way to create XML documents by using XmlWriter.

The xml writer class outputs XML data to a stream or file in a forward-only (forward-only) way. More importantly, the XML writer is designed to ensure that all XML data conforms to the XML 1.0 recommendation, and you don't even have to worry about forgetting to write the tag, because XML writer will help you write it. XmlWriter is an abstract base class for all XML writer. The. NET Framework provides only one writer class----XmlTextWriter class.

Let's take a look at the differences between the XML writers and the old writers, and the following code holds an array of string types:

StringBuilder sb = new StringBuilder ("");

Sb. Append ("");

foreach (string s in TheArray) {

Sb. Append ("
Sb. Append (s);

Sb. Append ("\\\\\\\\"/>);

}

Sb. Append ("");

The code loops through the elements in the data, writes the label text, and accumulates them into a string. The code guarantees that the output is well-formed and notes the indentation of the new line, and supports namespaces. This approach may not be an error when you create a document structure that is simpler. However, when you want to support processing instructions, namespaces, indents, formatting, and entities, the number of code grows exponentially, and the likelihood of error increases.

The xml writer Write method feature corresponds to each possible XML node type, which makes the process of creating XML documents more logical and less reliant on cumbersome markup languages. Figure six illustrates how to connect a string data using the XmlTextWriter class method. The code is concise, and XML-writer code is easier to read and better structured.

Figure 6 serializing a String Array

void Createxmlfileusingwriters (string[] thearray, String filename)

{

Open the XML writer (with 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 input errors. XML writer does not check that element names and property names are valid, nor does it guarantee that any Unicode characters used are appropriate for the current schema's encoding set. As mentioned above, in order to avoid output errors, non-XML characters must be eliminated. But writer did not provide this method.

In addition, when you create an attribute node, writer does not verify that the name of the attribute node is the same as the name of an existing element node. Finally, the XmlWriter class is not a writer class with validation, nor does it guarantee that the output conforms to a schema or a DTD. The writer class with validation in the. NET framework is not currently available. But in my applied XML programming for Microsoft. NET (Microsoft Press?, 2002), I wrote a writer component with validation on my own. You can go to the following URL to download the source code:http://www.microsoft.com/MSPress/books/6235.asp.

Figure Seven lists some status values (state) of the XML writer. These values are derived from the WriteState enumeration class. When you create a writer, its initial state is start, which means that you are about to configure the object, in fact writer did not start. The next state is the Prolog, which is set when you call the WriteStartDocument method to start working. Then, the transformation of the State depends on the content of the document and the document that you are writing. The Prolog state remains until you add a non-element node, such as annotation elements, processing instructions, and document types. When the first node is the root node is written, the state becomes an element. When you call the Writerstartatribute method, the state is converted to attribute, not when you invoke the Writeatributestring method to write the property. In that case, the state should be element. When you write a closed tag (>), the state is converted to content. When you have finished writing the document, call the WriteEndDocument method and the state will return to start until you start writing another document or turn off the writer.

Figure 7 States for XML Writer

State
Description

Attribute
The writer enters this ' when ' is being written

Closed
The Close method has been called and the writer are no longer available for writing operations

Content
The writer enters the content of a node is being written

Element
The writer enters this state when a 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 a initial state, awaiting for a write call to be issued


writer the output text inside a buffer. Typically, the buffer is refreshed or cleared, and the XML text should be written before the writer is closed. At any time, you can empty the buffer by calling the Flush method, write the current content to the stream (through the BaseStream attribute to expose the stream), and then release the partially occupied memory, and writer remain open (the open state) to continue. Note that although some of the document content is written, other programs cannot process the document until writer is closed.

You can write attribute nodes in two ways. The first method is to use the Writestartatribute method to create a new attribute node and update the writer state. The property value is then set with the WriteString method. When you finish writing, end the node with the WriteEndElement method. Alternatively, you can use the WriteAttributeString method to create a new attribute node, and when the Writerr state is element, Writerattributestring starts working, creating a separate attribute. Similarly, the WriteStartElement method writes the node's start tag (<), and then you can set the node's properties and text content randomly. The closed tag of the element node is labeled "/>". If you want to write a closed tag, you can use the Writefullendelement method to write.

You should avoid sensitive markup characters in the text that is passed to the Write method, such as the less-than sign (<). The string that writes the stream with the WriteRaw method is not parsed, and we can use it to write a special string to the XML document. The following two lines of code, the first line of output is "<", the second line output "<":

Writer. WriteString ("<");

Writer. WriteRaw ("<");



Read and write stream

Interestingly, reader (reader) and writer classes provide a way to read and write data streams based on Base64 and BinHex encodings. The functions of the WriteBase64 and Writebinhex methods are slightly different from those of other writing methods. They are all based on streaming, and the two methods function like a byte array instead of a string. The following code first converts a string to a byte array and then writes them as a Base64 encoding stream. The GetBytes static method of the encoding class completes the transformation task:

Writer. WriteBase64 (

Encoding.Unicode.GetBytes (BUF),

0, buf. LENGTH*2);

The code in Figure VIII illustrates the conversion of a string data to a BASE64 encoded XML stream. Figure IX is the result of the output.


Figure 8 Persisting 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 an 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);

Sets the child elements to indent according to indentation and IndentChar. This option indents only the content of the element

XMLW. formatting = formatting.indented;

XML declaration with write version "1.0"

XMLW. WriteStartDocument ();

Writes out a comment that contains the specified text.

XMLW. WriteComment ("Array to Base64 XML");

Start writing out the array node

XMLW. WriteStartElement ("array");

Writes out the properties with the specified prefix, local name, namespace URI, and value

XMLW. WriteAttributeString ("xmlns", "X", NULL, "Dinoe:msdn-mag");

The child node of the loop that writes the array

foreach (string s in TheArray)

{

Writes out the specified opening tag and associates it with a given namespace and prefix

XMLW. WriteStartElement ("x", "element", NULL);

Converts s to a byte[] array, encodes the byte[] array as Base64 and writes out the resulting text, the number of bytes to be written is twice times the total length of s, and the number of bytes in a string is 2 bytes.

XMLW. WriteBase64 (Encoding.Unicode.GetBytes (s), 0, s.length*2);

Close child nodes

XMLW. WriteEndElement ();

}

Close root node, only level two

XMLW. WriteEndDocument ();



Close writer

XMLW. Close ();



read out what is written

XmlTextReader reader = new XmlTextReader (Filname);

while (reader. Read ())

{

Get node with node name 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 ();



}

}

figure 9 String Array in Internet Explorer

The reader class has specific methods for interpreting Base64 and BinHex encoded streams. The following code fragment demonstrates how to parse a document created with a Base64 and BinHex encoding set using the ReadBase64 method of the XmlTextReader class.

XmlTextReader reader = new XmlTextReader (filename);

while (reader. Read ()) {

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 ();

The conversion from byte to string is accomplished by the GetString method of encoding class. Although I only introduced the code based on the BASE64 code set, but can simply replace the method name with BinHex can be read based on BinHex encoded node content (with the ReadBinHex method). This technique can also be used to read any binary data expressed in the form of byte data, especially data of image type.

Author: Chyich (translation)/aspcool



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.