The best practices that represent XML in .NET Framework
Release Date: 8/25/2004
| Update Date: 8/25/2004
Dare Obasanjo
Microsoft Corporation
Summary: Dare Obasanjo focuses on the options that can be used to represent, XML-based data, and discuss the advantages and disadvantages of each method within a single process and an AppDomain.
introduction
After recent design review, a position is whether the project manager is inquiry whether there is design guidelines when public XML is disclosed in the API, because he has seen many different methods, but it is impossible to determine what method of the choice. I told him that I was originally believed to find some guidelines on the MSDN, but when I gave it, I only found a piece of MSDN TV titled Passing XML Data Inside The CLR (English), although it contains such information, it is not easy. read. So I sprout such a thought, providing a version of the MSDN TV fragment of Don Box, and provides some experience in Microsoft to process XML APIs.
Back to top
Probe into the guideline
In three main cases, developers need to consider using what API to represent XML. The following is a brief introduction to these conditions and guidelines:
• The field or attribute contains XML: If the field or attribute of the class is an XML document or segment, the class should provide a mechanism that operates its properties as a string and XmlReader. • Method can accept XML input or return XML as an output: method of accepting or returning XML should help return XMLReader or XPathnavigator unless the user wants to edit XML data (this should be used to use XMLDocument). • Convert objects to XML: If the object is used to represent its own use of XML, it should use XMLWriter when the XML serialization process control is more than XMLSERIALIZER. If the object is to indicate itself in XML, it is possible to participate in the identity of XML world members (if XPath query or XSLT conversion is allowed on this object), this object should implement the IXPathnavigable interface.
In the parties below, I introduced the few situations mentioned above and explained how I got these guidelines.
Back to top
Common doubt
When you decide to use the method or attribute to accept or return XML, many classes in the .NET Framework will appear in your brain, which are applicable to this task. The following is listed below, and five classes that are best suited to represent XML inputs or outputs are given in the .NET Framework, and given a brief description of its positive opposition.
1. System.xml.xmlreader (English): XmlReader is the Plus-mode XML Analysis program for .NET Framework. During the pull model processing, the XML user controls the program stream by requesting an event from an XML manufacturer as needed. The pull-type XML analysis program (such as XMLReader) operates with only flow mode while only displaying information about a single node at any given time. In fact, XmlReader does not require the entire XML document to load into memory and is read-only, which makes it a good choice for creating an XML appearance in non-XML data sources. An example of creating an XML appearance in non-XML data sources is XMLCSVReader (English). Some people may regard XmlReader's only characteristics as a limitations because it cannot be passed multiple times by using each part of the XML document. 2. System.xml.xpath.xpathnavigator (English): XPathnavigator is a read-only cursor on the XML data source. The XML cursor is like a lens, focusing on an XML node at a time, but is different from the pull-based API (such as XmlReader), which can position the cursor at any location of the XML document at any given time. To a certain extent, the pull-up API is the only version of the cursor model. XPathnavigator is a good candidate for XML appearance in non-XML data because it allows you to construct an XML view of the data source in real time without having to convert the entire data source into an XML tree. An example of an XML view using XPathnavigator to create non-XML data is Objectxpathnavigator (English). In fact, Xpathnavigator is read-only and lacks some user-friendly properties (such as InnerXML (English) and OuterXML (English)), which makes it impossible to use XMLDocument or XMLNode when needed. 3. System.xml.xmlwriter (English): XMLWRITER provides general mechanisms that push XML documents into basic storage areas. The basic storage area can be from a file (if using xmlTextWriter) to XMLDocument (if you are using XMLNodeWriter (English)) anything. The parameters using XMLWRITER as a way to return XML provide a reliable way to support various possible return types (including file streams, strings, and xmldocument instances). That's why XMLSerializer.Serialize () Method accepts XMLWriter as a parameter on one of the overloads. As the meaning of its name, XMLWriter is only useful to write XML, and cannot be used to read or process XML. 4. System.xml.xmldocument / XMLNode (English): XMLDocument is the implementation of W3C Document Object Model (DOM) (English). The DOM is a representation of the XML document configured by the layered tree of the XMLNode object, which represents the logical components of the XML document, such as elements, attributes, and text nodes.
The DOM is the most popular API of XML in the .NET Framework, as it provides a direct method to load, process, and save XML documents. The main defect of the DOM is that its design needs to load the entire XML document into memory. 5. System.String (English): XML is a text-based format and is better than the String class. The main advantage of using a string as an XML representation is that the string is the least blended mother. The string is easy to write to the log file or print it to the console, and if you want to use the XML API to actually handle the XML, you can load the string into XMLDocument or XPathDocument. Use strings as several issues in the main input or output of methods or attributes using XML. The first problem using the string is similar to the DOM, which requires loading the entire XML document into memory. Second, in a string, XML will increase the burden of the manufacturer to generate an XML string, in some cases, this may be very troublesome. An example that generates an XML string may be very troublesome to get XML from XMLReader or XPathnavigator. Third, the string represents XML may result in confusion related to character encoding, as what code declaration is placed in XML, the string in .NET Framework is always UTF-16 character encoding. Finally, the XML is represented by a string so that the XML processing pipe is difficult because each layer in the pipe must reassure the document. Back to top
The field or attribute contains XML
In some cases, the field or attribute of the object may be an XML document or an XML fragment. The following example class represents an e-mail, its content is XHTML. The XML content of the message is represented by a string and is disclosed by the Body property of the class:
PUBLIC CLASS Email {
PRIVATE STRING FROM;
Public string from {
Get {return from;
Set {from = value;}
}
PRIVATE STRING TO;
Public string to {
Get {return to;}
Set {to = value;}
}
PRIVATE STRING SUBJECT;
Public String Subject {
Get {returnis subject;}
Set {Subject = Value;}
}
PRIVATE DATETIME SENT;
Public DateTime SENT {
Get {return Sent;
SET {Sent = Value;}
}
Private xmldocument body = new xmldocument ();
Public string body {
Get {return body.outerXML;
Set {body.load (new system.io.stringreader (value);}
}
}
The main representation of the field or attribute representing the XML document is the most user-friendly representation method because the System.String class is the most familiar XML "common doubt" that general developers. However, this will increase the burden of the user using this class, which may now have to deal with the cost of analyzing the XML document twice. For example, an idea is intended: such an attribute is set in XML obtained from SQLCommand.executexmlReader () Method (English) or XSLTRRANSFORM.TRANSFORM () Method (English). In this case, the user will have to analyze the document twice, as shown in the following example: email email = new email ();
Email.from = "Dareo@example.com";
Email.to = "Michealb@example.org";
Email.subject = "Hello World";
XSLTransform Transform = New XslTransform ();
Transform.Load ("format-body.xsl");
XMLDocument body = new xmldocument ();
// 1. XML is analyzed by xmlDocument.load ()
Body.Load (Transform.Transform (New XpathDocument ("Body.xml"), NULL);
// 2. The same XML is analyzed again by XMLDocument.Load () in the Email.Body property
Email.body = body.outerxml;
In the above example, the same XML is analyzed twice, because the XMLReader must be loaded into the XMLDocument before converting the XML into a string, and then use the XML to set the body of the Email class, then the attribute itself The XML is analyzed intern to XMLDocument. A very effective manner is to provide access to XML properties (as XmlReader and strings). Therefore, the following methods should also be added to the Email class to make the user's maximum flexibility:
Public void setBody (XmlReader Reader) {
Body.Load (Reader);
}
Public xmlreader getBody () {
Return New XMLNodeReader (Body);
}
This provides a way for the Email class that allows these users to deliver, set, and retrieve XML data in a valid manner when needed.
Criterion If the field or attribute of the class is an XML document or a clip, the class should provide a mechanism to operate its properties simultaneously as a string and XmlReader.
A keen reader may notice that if you disclose XMLDocument directly, you should meet the criteria, and the user should make the user to exact XML.
Back to top
Method can accept XML input or return XML as an output
When designing or using XML methods, developers have a responsibility to make such a method flexibility in receiving input. When the method accepts XML as an input, you can divide these methods into methods requiring data to modify the data in place, and simply use only read-only access to XML. The only "XML Common Dosage" supporting read and write is XMLDocument. The following code example shows such a method:
Public void applydiscount (xmlDocument price) {foreach (xmlelement price in pricelist.selectnodes) {
Price.innertext = (Double.Parse (Price.innerText) * 0.85) .tostring ();
}
}
There are two main options for read-only access to XML:
• XmlReader • XPathnavigator
XmlReader provides only access to XML, but Xpathnavigator not only provides random access to basic XML sources, but also provides the ability to perform XPath queries for data sources. The following code example will print Artist (artist) and Title in the XML document below:
compact-disc>
compact-disc>
items>
XmlReader:
Public Static Void PrintArtistandprice (XMLReader Reader) {
Reader.moveTocontent (); //move from root node to document element (item)
/ * Keep read until you get the first
While (Reader.Read ()) {
IF ((Reader.NodeType == XMLNodeType.element) && reader.name.equals ("artist")) {
Artist = Reader.Readelementstring ();
Title = Reader.ReadeElementstring ();
Break;
}
}
Console.writeline ("Artist = {0}, Title = {1}", Artist, Title;
}
}
Xpathnavigator:
Public Static Void PrintArtistandprice (Xpathnavigator NAV) {
XpathnodeEiterator Iterator = nav.select ("/ items / compact-disc [1] / artist
| / Items / Compact-Disc [1] / Title ");
Iterator.movenext ();
Console.writeLine ("Artist = {0}", Iterator.current);
Iterator.movenext ();
Console.writeline ("Title = {0}", Iterator.current);
}
Typically, a similar rule is used by returning XML. If you want the recipient to edit XML, you should return XMLDocument. Otherwise, it should be returned to XMLReader or XPathnavigator based on whether only only flowing access to XML data is required. The method accepting or returning XML should help return XMLReader or XPathnavigator unless the user wants to edit XML data (this clock should be used.
The above guidelines means that the way to return XML should help return XMLReader because it applies more to more users than any other type. In addition, when the modem needs to more function, they can load XMLDocument or XPathDocument from the returned XMLReader.
Back to top
Convert object to XML
XML as a general language of information exchange has nothing, which makes it an obvious option to indicate some objects of itself in XML, these objects or sequence-based dedication, or to obtain access to other XML technology (eg Use XPath to query or use XSLT for conversion).
When converting objects into XML for serialization, it is clear that the XML Serialization Technology in The .NET Framework (English) should be selected. However, in some cases, your control required to generate the XML may be more than XMLSerializer. In this case, the XMLWRITER in the kit is a very useful class because it makes you no longer need the structure of the structure and a one-to-one map between the generated XML. The following example shows the XML generated by using the XMLWRITER serialization Email class (previously mentioned in the previous sections).
Public void save (xmlwriter write) {
Writer.writestartDocument ();
Writer.writestartElement ("email");
Writer.writestartElement ("Headers");
Writer.writestartElement ("header");
Writer.writeElementString ("Name", "to");
Writer.writeElementstring ("Value", this.to);
Writer.writeEndelement (); // Title
Writer.writestartElement ("header");
Writer.writeElementstring ("Name", "from");
Writer.writeElementstring ("Value", this.from);
Writer.writeEndelement (); // Title
Writer.writestartElement ("header");
Writer.writeElementString ("Name", "Subject");
Writer.writeElementstring ("Value", this.subject;
Writer.writeEndelement (); // Title
Writer.writestartElement ("header");
Writer.writeElementString ("Name", "SENT");
Writer.writeElementstring ("Value", Xmlconvert.toString (this.sent); Writer.WriteEndelement (); // Title
Writer.writeEndelement (); // Title;
Writer.writestartElement ("body");
Writer.writeraw (this.body);
Writer.writeEndDocument (); // Close all open tags
}
This code generates the following XML document
header>
header>
header>
header>
headers>
Hello World is my favorite sample application. p> body>
email>
The basic feature of using only XMLSerializer will not be possible to generate the above XML document. Another advantage of XMLWriter is that it can extract from the basic target to the target to be written, so it can be any content of the file from the disk to the memory (even XMLNodeWriter's XMLDocument scales).
If a way is required, the class can be more fully involved in the XML world (such as XML technology and other XML technology), the best choice for this class is to implement the IXPathnavigable interface and provide Xpathnavigator for this class. An example of this is ObjectxPathnavigator, which provides an XML view for any object that enables you to perform XPath queries or run XSLT conversions on the above object.
Guidelines If the object is in XML to represent its own as a serialization, the XML serialization process control is more than the more time provided by XMLSerializer, and XMLWRITER should be used. If the object is to indicate itself in XML, it is possible to participate in the identity of XML world members (if XPath query or XSLT conversion is allowed on this object), this object should implement the IXPathnavigable interface.
Back to top
in conclusion
In future .NET Framework versions, it will greatly emphasize the cursor-based XML API (Xpathnavigator, which is disclosed by the IXPathnavigable interface). This type of cursor will become a main mechanism for interacting with XML in .NET Framework.
Dare Obasanjo is a member of the Microsoft WebData team, except for other transactions, the team also developed .NET Framework's System.xml and System.Data Namespace, Microsoft XML Core Services (MDAC), and Microsoft Data Access Components (MDAC) Component. For any questions or comments on this article, please post to the extra XML message board on the GotdotNet.