For XML, I think everyone knows it well. I don't need to bother to describe what it is. I think XML will surely shine in the future of Web development, XML is a scalable markup language, which allows enterprises to develop their own data formats, data is transmitted over the network according to this format and then converted into the desired format through XSLT, which easily solves the problem of incompatible data formats. For Internet data transmission, I think this is the most attractive place for our programmers!
Our topic today is not about the advantages of XML, but about how to use XML in C. Next, let's take a look at some basic theoretical knowledge about accessing XML using a program.
Two access models:
There are two models for accessing and then operating XML files in a program: DOM (Document Object Model) and stream model. The advantage of DOM is that it allows editing and updating XML documents, you can randomly access the data in the document and use XPath for query. However, the disadvantage of DOM is that it needs to load the entire document to the memory at a time. For large documents, this may cause resource problems. The stream model solves this problem well because it uses the stream concept to access XML files, that is, it only has the current node in the memory at any time, but it also has its shortcomings. It is read-only and only forward, and cannot perform backward navigation in the document. Although each has its own merits, we can also use the two in the program to complement each other! Today, we will mainly discuss XML reading. Let's discuss the stream model in detail!
Variations in the stream model:
The stream model iterates one node in the XML document each time. It is suitable for processing large documents and consumes less memory. The stream model has two variants: the "push" model and the "pull" model.
The push model is also commonly referred to as SAX. SAX is an event-driven model. That is to say, every time it discovers a node, it uses the PUSH model to trigger an event, however, we must write the processing programs for these events, which is very inflexible and troublesome.
. NET uses the implementation scheme based on the "pull" model. When traversing a document, the "pull" model will pull the part of the document that is interested from the reader without triggering events, allow us to access documents in a programmatic manner, which greatly improves flexibility. In terms of performance, the "pull" model can be used to process nodes selectively. Every time a node is found in SAX, it notifies the client, the "pull" model can improve the overall efficiency of the Application. In. NET, the "pull" model is implemented as an XmlReader class. Let's take a look at the inheritance structure of this class:
Let's talk about the XmlTextReader class in this architecture. This class provides the ability to read Xml files. It can verify whether the documents are in good format. If not, this class will throw an XmlException exception during reading. You can use some methods provided by this class to read, filter, and obtain the node name and value. Please remember: xmlTextReader is based on the implementation of the stream model. In an inappropriate analogy, the XML file is like a water source. When the gate is opened, the water flow will flow, and it will not flow back. The memory only contains the current node at any time. You can use the Read () method of the XmlTextReader class to Read the next node. Now, let's look at an example. You should pay attention to the actual programming, right. Let's take a look at the running effect before reading the code!
Example1 traverses the document to read data, Example2 and Example3 obtain the node type, Example4 filters the document to get only the data content, Example5 gets the attribute node, Example6 gets the namespace, and Example7 shows the entire XML document, to this end, I specifically write a class to encapsulate the above functions. The code for this class is as follows:
// Configure //---------------------------------------------------------------------------------------------------
// The XmlReader class is used for reading Xml files. The following describes the class:
//
// Attributes (attribute ):
// ListBox: set this attribute to obtain the client control to display the content of the file read. (The ListBox control is used here)
// Xmlpath: set this attribute to obtain the absolute path of a specified XML file.
//
// Basilic using (important reference ):
// System. xml: This namespace encapsulates common classes for XML operations. The xmltextreader class is used in this class.
// Xmltextreader: This class provides the ability to read XML files. It can verify whether the file format is good. If it is not a formatted XML file, this class will throw an xmlexception exception during reading. You can use
// Some methods are used to read, filter, and obtain the node name and value.
//
// Bool xmltextreader. Read (): reads the next node in the stream. After reading the last node, call this method again. This method returns false.
// Xmlnodetype xmltextreader. nodetype: Type of the current node returned by this attribute
// Xmlnodetype. Element Node
// Xmlnodetype. endelement End Element Node
// The first node of the xmlnodetype. xmldeclaration document
// Xmlnodetype. Text text node
// Bool xmltextreader. hasattributes: whether the current node has any attribute. True or false is returned.
// String xmltextreader. Name: returns the name of the current node.
// String xmltextreader. Value: returns the value of the current node.
// String xmltextreader. localname: returns the local name of the current node.
// String xmltextreader. namespaceuri: returns the namespace URI of the current node.
// String xmltextreader. Prefix: returns the prefix of the current node.
// Bool xmltextreader. movetonextattribute (): Move to the next attribute of the current node
// Configure //---------------------------------------------------------------------------------------------------
Namespace xmlreading
{
Using system;
Using system. xml;
Using system. Windows. forms;
Using system. componentmodel;
/// <Summary>
/// XML file Reader
/// </Summary>
Public class xmlreader: idisposable
{
Private string _ xmlpath;
Private const string _ errmsg = "error occurred while reading ";
Private ListBox _ ListBox;
Private xmltextreader xmltxtrd;
# Region xmlreader Constructor
Public xmlreader ()
{
This. _ xmlPath = string. Empty;
This. _ listBox = null;
This. xmlTxtRd = null;
}
/// <Summary>
/// Constructor
/// </Summary>
/// <Param name = "_ xmlPath"> absolute path of the xml file </param>
/// <Param name = "_ listBox"> The listBox is used to display xml. </param>
Public XmlReader (string _ xmlPath, ListBox _ listBox)
{
This. _ xmlPath = _ xmlPath;
This. _ listBox = _ listBox;
This. xmlTxtRd = null;
}
# Endregion
# Region XmlReader resource Release Method
/// <Summary>
/// Clear all resources in use for this object
/// </Summary>
Public void Dispose ()
{
This. Dispose (true );
GC. SuppressFinalize (this );
}
/// <Summary>
/// Release the instance variable of this object
/// </Summary>
/// <Param name = "disposing"> </param>
Protected virtual void Dispose (bool disposing)
{
If (! Disposing)
Return;
If (this. xmlTxtRd! = Null)
{
This. xmlTxtRd. Close ();
This. xmlTxtRd = null;
}
If (this. _ xmlPath! = Null)
{
This. _ xmlPath = null;
}
}
# Endregion
# Region XmlReader attributes
/// <Summary>
/// Get or set the list box to display xml
/// </Summary>
Public ListBox listBox
{
Get
{
Return this. _ listBox;
}
Set
{
This. _ listBox = value;
}
}
/// <Summary>
/// Obtain or set the absolute path of the xml file
/// </Summary>
Public string xmlPath
{
Get
{
Return this. _ xmlPath;
}
Set
{
This. _ xmlPath = value;
}
}
# Endregion
/// <Summary>
/// Traverse the Xml file
/// </Summary>
Public void EachXml ()
{
This. _ listBox. Items. Clear ();
This. xmlTxtRd = new XmlTextReader (this. _ xmlPath );
Try
{
While (xmlTxtRd. Read ())
{
This. _ ListBox. Items. Add (this. xmltxtrd. value );
}
}
Catch (xmlexception exp)
{
Throw new xmlexception (_ errmsg + this. _ xmlpath + exp. tostring ());
}
Finally
{
If (this. xmltxtrd! = NULL)
This. xmltxtrd. Close ();
}
}
/// <Summary>
/// Read the node type of the XML file
/// </Summary>
Public void readxmlbynodetype ()
{
This. _ ListBox. Items. Clear ();
This. xmltxtrd = new xmltextreader (this. _ xmlpath );
Try
{
While (xmltxtrd. Read ())
{
This. _ ListBox. Items. Add (this. xmltxtrd. nodetype. tostring ());
}
}
Catch (XmlException exp)
{
Throw new XmlException (_ errMsg + this. _ xmlPath + exp. ToString ());
}
Finally
{
If (this. xmlTxtRd! = Null)
This. xmlTxtRd. Close ();
}
}
/// <Summary>
/// Filter Xml documents based on node types
/// </Summary>
/// <Param name = "xmlNType"> array of the XmlNodeType node type </param>
Public void FilterByNodeType (XmlNodeType [] xmlNType)
{
This. _ listBox. Items. Clear ();
This. xmlTxtRd = new XmlTextReader (this. _ xmlPath );
Try
{
While (xmlTxtRd. Read ())
{
For (int I = 0; I <xmlNType. Length; I ++)
{
If (xmlTxtRd. NodeType = xmlNType [I])
{
This. _ listBox. Items. Add (xmlTxtRd. Name + "is Type" + xmlTxtRd. NodeType. ToString ());
}
}
}
}
Catch (XmlException exp)
{
Throw new XmlException (_ errMsg + this. xmlPath + exp. ToString ());
}
Finally
{
If (this. xmlTxtRd! = Null)
This. xmlTxtRd. Close ();
}
}
/// <Summary>
/// Read all the text node values of the Xml file
/// </Summary>
Public void ReadXmlTextValue ()
{
This. _ listBox. Items. Clear ();
This. xmlTxtRd = new XmlTextReader (this. _ xmlPath );
Try
{
While (xmltxtrd. Read ())
{
If (xmltxtrd. nodetype = xmlnodetype. Text)
{
This. _ ListBox. Items. Add (xmltxtrd. value );
}
}
}
Catch (xmlexception xmlexp)
{
Throw new xmlexception (_ errmsg + this. _ xmlpath + xmlexp. tostring ());
}
Finally
{
If (this. xmltxtrd! = NULL)
This. xmltxtrd. Close ();
}
}
/// <Summary>
/// Read the attributes of the XML file
/// </Summary>
Public void readxmlattributes ()
{
This. _ ListBox. Items. Clear ();
This. xmltxtrd = new xmltextreader (this. _ xmlpath );
Try
{
While (xmltxtrd. Read ())
{
If (xmltxtrd. nodetype = xmlnodetype. element)
{
If (xmltxtrd. hasattributes)
{
This. _ ListBox. Items. Add ("the element" + xmltxtrd. Name + "has" + xmltxtrd. attributecount + "attributes ");
This. _ ListBox. Items. Add ("the attributes are :");
While (xmltxtrd. movetonextattribute ())
{
This. _ ListBox. Items. Add (xmltxtrd. Name + "=" + xmltxtrd. value );
}
}
Else
{
This. _ ListBox. Items. Add ("the element" + xmltxtrd. Name + "has no attribute ");
}
This. _ ListBox. Items. Add ("");
}
}
}
Catch (xmlexception xmlexp)
{
Throw new xmlexception (_ errmsg + this. _ xmlpath + xmlexp. tostring ());
}
Finally
{
If (this. xmltxtrd! = NULL)
This. xmltxtrd. Close ();
}
}
/// <Summary>
/// Read The namespace of the XML file
/// </Summary>
Public void readxmlnamespace ()
{
This. _ ListBox. Items. Clear ();
This. xmltxtrd = new xmltextreader (this. _ xmlpath );
Try
{
While (xmltxtrd. Read ())
{
If (xmltxtrd. nodetype = xmlnodetype. Element & xmltxtrd. prefix! = "")
{
This. _ listBox. Items. Add ("The Prefix" + xmlTxtRd. Prefix + "is associated with namespace" + xmlTxtRd. NamespaceURI );
This. _ listBox. Items. Add ("The Element with the local name" + xmlTxtRd. LocalName + "is associated with" + "the namespace" + xmlTxtRd. NamespaceURI );
}
If (xmlTxtRd. NodeType = XmlNodeType. Element & xmlTxtRd. HasAttributes)
{
While (xmlTxtRd. MoveToNextAttribute ())
{
If (xmlTxtRd. Prefix! = "")
{
This. _ listBox. Items. Add ("The Prefix" + xmlTxtRd. Prefix + "is associated with namespace" + xmlTxtRd. NamespaceURI );
This. _ listBox. Items. Add ("The Attribute with the local name" + xmlTxtRd. LocalName + "is associated with the namespace" + xmlTxtRd. NamespaceURI );
}
}
}
}
}
Catch (xmlexception xmlexp)
{
Throw new xmlexception (_ errmsg + this. _ xmlpath + xmlexp. tostring ());
}
Finally
{
If (this. xmltxtrd! = NULL)
This. xmltxtrd. Close ();
}
}
/// <Summary>
/// Read the entire XML file
/// </Summary>
Public void readxml ()
{
String attandele = string. empty;
This. _ ListBox. Items. Clear ();
This. xmltxtrd = new xmltextreader (this. _ xmlpath );
Try
{
While (xmltxtrd. Read ())
{
If (xmltxtrd. nodetype = xmlnodetype. xmldeclaration)
This. _ ListBox. Items. Add (string. Format ("<? {0} {1}?> ", Xmltxtrd. Name, xmltxtrd. Value ));
Else if (xmltxtrd. nodetype = xmlnodetype. element)
{
Attandele = string. Format ("<{0}", xmltxtrd. Name );
If (xmltxtrd. hasattributes)
{
While (xmltxtrd. movetonextattribute ())
{
Attandele = attandele + String. Format ("{0} = '{1}'", xmltxtrd. Name, xmltxtrd. value );
}
}
Attandele = attandele. Trim () + "> ";
This. _ ListBox. Items. Add (attandele );
}
Else if (xmltxtrd. nodetype = xmlnodetype. endelement)
This. _ ListBox. Items. Add (string. Format ("</{0}>", xmltxtrd. Name ));
Else if (xmltxtrd. nodetype = xmlnodetype. Text)
This. _ listBox. Items. Add (xmlTxtRd. Value );
}
}
Catch (XmlException xmlExp)
{
Throw new XmlException (_ errMsg + this. _ xmlPath + xmlExp. ToString ());
}
Finally
{
If (this. xmlTxtRd! = Null)
This. xmlTxtRd. Close ();
}
}
}
}