The Nodes of an XML File |
|
An XML file appears as an upside-down tree: it has a root element, branches, and trees. As we have seen in the previous lesson, all of these objects are created using the same technique: a tag with a name and an optional value. Based on their similarities, these objects can be referred to as nodes. Here is an example: <?xml version="1.0" encoding="utf-8"?> <Videos> <Video> <Title>The Distinguished Gentleman</Title> <Director>Jonathan Lynn</Director> <Length>112 Minutes</Length> <Format>DVD</Format> <Rating>R</Rating> </Video> <Video> <Title>Her Alibi</Title> <Director>Bruce Beresford</Director> <Length>94 Mins</Length> <Format>DVD</Format> <Rating>PG-13</Rating> </Video> </Videos> To support nodes of an XML file, the .NET Framework provides the XmlNode class, which is the ancestor of all types of nodes.
Because an XML file can have different kinds of nodes, to be able to identify them, each node is recognized by its specific type. The types of node of an XML file are stored in the XmlNodeType enumerator. We will review them as it becomes necessary.
As seen in the previous lesson, one node can be nested inside of another. In that case, the nested node is called a child of the nesting node, which is a parent node. This also implies that a node can have as many children as you judge necessary, making child nodes of the parent node. In the above example, the Title and the Director nodes are children of the Video node. The Video node is the parent of both the Title and the Director node. To support the child nodes of a particular node, the XmlNode class is equipped with the ChildNodes property that is declared as follows: public: __property virtual XmlNodeList* get_ChildNodes(); This property produces a value of type XmlNodeList which is its own class. To get the whole text of the values of the children of a node, access its InnerText property which is declared as follows: public: __property virtual String* get_InnerText(); public: __property virtual void set_InnerText(String*); This property concatenates the values of the children of the node that called them. If you want to get a node, its markup, its child(ren) and its(their) markup(s), you can access its OuterXml property which is declared as follows: public: __property virtual String* get_OuterXml(); If you want only the markup(s) of the child(ren) excluding the parent, access its InnerXml property which is declared as follows: public: __property virtual String* get_InnerXml();
Not all nodes have children, obviously. For example, the Title node in the above example doesn't have children. To find out whether a node has children, check its HasChildNodes Boolean property that is declared as follows: public: __property virtual bool get_HasChildNodes(); If a node is a child, to get its parent, you can access its ParentNode property.
The children of a nesting node are also recognized by their sequence. Based on this, the first element that immediately follows the start-tag of the parent element is called the first child. In the case of the above file, the first <Video> node under <Videos> is the first child of the Video node. In the .NET Framework, the first child of a node can be retrieved by acccessing the XmlNode::FirstNode property declared as follows: public: __property virtual XmlNode* get_FirstChild(); Here is an example of getting the first child of the XML file: System::Void button2_Click(System::Object * sender, System::EventArgs * e) { XmlDocument *docXML = new XmlDocument; docXML->Load(S"Videos.xml"); XmlNode *firstBorn = docXML->FirstChild; }
As opposed to the first child, the child node that immediately precedes the end-tag of the parent node is called the last child. To get the last child of a node, you can access its XmlNode::LastChild property that is declared as follows: public: __property virtual XmlNode* get_LastChild();
The child nodes that are nested in a parent node and share the same level are referred to as siblings. Consider the following listing: <?xml version="1.0" encoding="utf-8"?> <Videos> <Video> <Title>The Distinguished Gentleman</Title> <Director>Jonathan Lynn</Director> <Actors> <Actor>Eddie Murphy</Actor> <Actor>Lane Smith</Actor> <Actor>Sheryl Lee Ralph</Actor> <Actor>Joe Don Baker</Actor> </Actors> <Length>112 Minutes</Length> <Format>DVD</Format> <Rating>R</Rating> </Video> <Video> <Title>Her Alibi</Title> <Director>Bruce Beresford</Director> <Length>94 Mins</Length> <Format>DVD</Format> <Rating>PG-13</Rating> </Video> </Videos> In this example, Director, Actors, and Length are child nodes of the Video node but the Actor node is not a child of the Video node. Consequently, Director, Actors, and Length are siblings. Obviously, to get a sibling, you must first have a node. Based on this, to access the sibling of a node, you can use its NextSibling property, which is declared as follows: public: __property virtual XmlNode* get_NextSibling();
A comment is a character, a line or a paragraph that is not considered as part of the XML code that needs to be processed. A comment allows you to insert notes or personal observations inside an XML file. For this reason, a commented section can be written any way you like. This means that a comment can include plain text, formulas, expressions, or even XML code as long as you know that that XML code will not be validated: it will ignored by the parser.
To create a comment, you use the following formula: <!-- Blah Blah Blah --> Between <!-- and -->, any text in that section is considered a comment and you can include anything you want. Both sections of the comment use two dashes, not more, not less. Here is an example: <?xml version="1.0" encoding="utf-8"?> <Videos> <Video> <!-- In this collection, we will keep each title "as is" --> <Title>The Distinguished Gentleman</Title> <Director>Jonathan Lynn</Director> <Length>112 Minutes</Length> <Format>DVD</Format> <Rating>R</Rating> </Video> <Video> <Title>Her Alibi</Title> <Director>Bruce Beresford</Director> <Length>94 Mins</Length> <Format>DVD</Format> <Rating>PG-13</Rating> </Video> </Videos> This would produce:
|
The System::Xml represents a comment through the XmlComment class. Like any other part of an XML file, a comment is represented by the XmlComment::Name property. This allows you to retrieve the name of a comment that is included in the document. To create a comment, you can call the XmlDocument::CreateComment() method. Its syntax is: public: virtual XmlComment* CreateComment(String* data); This method takes as argument the text that would go into the commented section. After calling it, if the method succeeds, which it usually does, it returns the XmlComment object that was created. Here is an example: |
// This is the main project file for VC++ application project // generated using an Application Wizard. #include "stdafx.h" #using <mscorlib.dll> #using <System.Xml.dll> using namespace System; using namespace System::Xml; int _tmain() { // TODO: Please replace the sample code below with your own. XmlDocument *docXML = new XmlDocument; docXML->LoadXml(S"<Videos><Video>" S"<!-- In this collection, we will keep each title \"as is\" -->" S"<Title>The Distinguished Gentleman</Title>" S"<Director>Jonathan Lynn</Director><Length>112 Minutes</Length>" S"<Format>DVD</Format><Rating>R</Rating></Video>" S"<Video><Title>Her Alibi</Title><Director>Bruce Beresford</Director>" S"<Length>94 Mins</Length><Format>DVD</Format><Rating>PG-13</Rating>" S"</Video></Videos>"); XmlComment *comXML = docXML->CreateComment(S"Personal Video Collection"); XmlElement *nodRoot = docXML->DocumentElement; docXML->InsertBefore(comXML, nodRoot); docXML->Save(Console::Out); Console::WriteLine(S"\n"); return 0; }
This would produce:
CDATA |
Except for comments, the parser is used to "scan" the whole XML file to analyze it. Every tag is then interpreted. As we mentioned already, the value of each tag can be displayed in a browser between its opening and its closing tag, and the browser uses different font styles to make a distinction. When creating some tags and some sections of the file, you may want the parser to consider those particular tags and sections as regular text. That is, you may want the parser to treat a certain tag and its value as if it were regular text even though it is created as an XML file. To prevent the parser from interpreting a tag regularly but to treat that tag and its value as regular text, you can create it in a CDATA section. To do this, create a section that starts with <![CDATA[, followed by anything you want, and ending with ]]>. The formula used is: <![CDATA[ Blah Blah Blah ]]> Between <![CDATA[ and ]]>, you can type anything, including one or more normal XML tags. Here is an example: |
<?xml version="1.0" encoding="utf-8"?> <Videos> <![CDATA[<VideoCollection>Personal Collection of Movies</VideoCollection>]]> <Video> <Title>The Distinguished Gentleman</Title> <Director>Jonathan Lynn</Director> <Length>112 Minutes</Length> <Format>DVD</Format> <Rating>R</Rating> </Video> <Video> <Title>Her Alibi</Title> <Director>Bruce Beresford</Director> <Length>94 Mins</Length> <Format>DVD</Format> <Rating>PG-13</Rating> </Video> </Videos>
The .NET Framework supports the creation of a CDATA section through the XmlCDataSection class. This class is equipped with a Name property that allows you t retrieve the name of a CDATA section in an XmlDocument object. To programmatically create a CDATA section, you can call the XmlDocument::CreateCDataSection() method. Its syntax is: public: virtual XmlCDataSection* CreateCDataSection(String* data); This method receives the content of the CDATA section as argument. If the method succeeds, which it usually does, it returns an XmlCDataSection value. Here is an example: |
// This is the main project file for VC++ application project // generated using an Application Wizard. #include "stdafx.h" #using <mscorlib.dll> #using <System.Xml.dll> using namespace System; using namespace System::Xml; int _tmain() { // TODO: Please replace the sample code below with your own. XmlDocument *docXML = new XmlDocument; docXML->LoadXml(S"<Videos><Video>" S"<!-- In this collection, we will keep each title \"as is\" -->" S"<Title>The Distinguished Gentleman</Title>" S"<Director>Jonathan Lynn</Director><Length>112 Minutes</Length>" S"<Format>DVD</Format><Rating>R</Rating></Video>" S"<Video><Title>Her Alibi</Title><Director>Bruce Beresford</Director>" S"<Length>94 Mins</Length><Format>DVD</Format><Rating>PG-13</Rating>" S"</Video></Videos>"); XmlCDataSection *xmlSection = docXML->CreateCDataSection(S"<ReleasedBy>Hollywood Pictures Company</ReleasedBy>"); XmlElement *nodRoot = docXML->DocumentElement; nodRoot->AppendChild(xmlSection); docXML->Save(Console::Out); Console::WriteLine(S"\n"); return 0; }
Node Removal |
If you have a node you don't want or don't need anymore in the file, you can delete it. To delete a node, the XmlNode class provides the RemoveChild() method. Its syntax is: public: virtual XmlNode* RemoveChild(XmlNode* oldChild); This method takes as argument the node to delete. If the node exists, it would be deleted and the method would return it. If the node doesn't exist, nothing would happen. To delete all child nodes of a node, you can call the XmlNode::RemoveAll() method. Its syntax is: public: virtual void RemoveAll(); When called, this method will remove all child nodes, if any, of their parent node. |
|
||
Previous | Copyright © 2004-2010 FunctionX, Inc. | |
|