XML reader compile and link – cpp

From the post of the full code of the xml reader project, full code here.

Here is how to compile it up and also link to a basic main run method.

Compile up

g++ cppxmlreader.cpp -c

will create the cppxmlreader.o (which is the object file) if you do file on the object the outout would be

file cppxmlreader.o
cppxmlreader.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

and then using this code xmlreadmain.cpp

#include "cppxmlreader.h"
 
int main(int argv, char** argc)
{
    xmlReader xmlRead;
    xmlRead.loadFile("words.xml");
    xmlRead.printOuterXML();
    return 0;
}

This will include the header file of the cppxmlreader.h and then create a xmlReader object and load a basic file of words.xml and then print out the xml read in.

Here is the words.xml

<?xml version="1.0" encoding="UTF-8"?>
<words>
  <word attname="hi">merry</word>
  <word>old</word>
  <word>sole</word>
  <word>was</word>
  <word>he</word>
</words>

and to compile up the main run the cppxmlreader.o is the object file from the above compiling and the xmlreadmain.cpp is the main runner with -o being the output name of the executable.

g++ xmlreadmain.cpp cppxmlreader.o -o xmlreader

and if you run the xmlreader, the output should be

XML Reader Main Object (Xml main details)
XML Object
Tagname  :
Tagvalue :
Attribute 0 : Name : version Value : 1.0
Attribute 1 : Name : encoding Value : UTF-8
XML Reader xml details
XML Object
Tagname  :words
Tagvalue :
XML Object
Tagname  :word
Tagvalue :merry
Attribute 0 : Name : attname Value : hi
XML Object
Tagname  :word
Tagvalue :old
XML Object
Tagname  :word
Tagvalue :sole
XML Object
Tagname  :word
Tagvalue :was
XML Object
Tagname  :word
Tagvalue :he
XML Object
Tagname  :/words
Tagvalue :

XML reader full – cpp

Here is the full code for the header and class file from the xml reader project

Here is the cppxmlreader.h file.

#ifndef CPPXMLREADER_H
#define CPPXMLREADER_H
 
#include <string>
#include <vector>
 
// using the namespace std for the string type, vector
using namespace std;
 
const int CHARACTERLENGHT = 80;
const string BADXMLVERSION = "Xml version - first line ? - problem";
const string BADTAGNAME = "Tag name was not present";
const string BADXMLTAGEND = "End tag is not the same as tag name";
const string BADATTRIBUTE = "Attribute in wrong format attributeName=\"attributeValue\"";
 
struct xmlAttribute {
    string _attributeName, _attributeValue;
};
 
class xmlObject {
  private :
    string _tagName, _tagValue;
    vector<xmlAttribute> _attributes;
    bool _xmlMainDetails;
 
  public:
      xmlObject() { _xmlMainDetails = false;} ;
      xmlObject(string tag, string tValue, xmlAttribute attribute);
 
      void setTagName(string tagName);
      void setTagValue(string tagValue);
      void addAttributes(xmlAttribute attribute);
      void setAttributeVector(vector<xmlAttribute> setAtt);
      void setXmlMainDetails(bool value);
      bool getXmlMainDetails();
      void printOutXmlObject();
};
 
class xmlReader {
  protected:
    vector<xmlObject> _xmlMainDetails;
    vector<xmlObject> _xmlDetails;
 
  public: 
    xmlReader();
 
    // open file and read in the xml file and place into the _xmlDetails
    bool loadFile(string filename);
    void printOuterXML();
 
  private :
    xmlObject readLine(string xmlToSplitUp, string* tagName);
    string readUntilCharacter(string line, char characterStart, char characterEnd, string *returnLine);
    xmlAttribute getAttribute(string attributeString);
    vector<xmlAttribute> getAttributesFromString(string str);
};
 
 
#endif // CPPXMLREADER_H

Here is the cppxmlreader.cpp file

#include "cppxmlreader.h"
#include <iostream>
#include <string.h>
#include <fstream>
 
using namespace std;
 
/* xmlObject */
// constructor for xmlObject, if any details are passed whilst constructing 
xmlObject::xmlObject(string tag, string tValue, xmlAttribute attribute)
{
  _tagName = tag;
  _tagValue = tValue;
  _attributes.push_back(attribute);
}
 
// xml <tagname attributes="attributesvalue">VALUE</tagname>
// set the tag name
void xmlObject::setTagName(string tagName)
{
  _tagName = tagName;
}
 
// set tag value
void xmlObject::setTagValue(string tagValue)
{
  _tagValue = tagValue;
}
 
// add attributes to the vector attributes variable
void xmlObject::addAttributes(xmlAttribute attribute)
{
  _attributes.push_back(attribute);
}
 
// fill in the vector attributes variable.
void xmlObject::setAttributeVector(vector<xmlAttribute> setAtt)
{
  _attributes = setAtt;
}
 
// print out the xml object detais, with the attributes values.
void xmlObject::printOutXmlObject()
{
  cout << "XML Object" << endl;
  cout << "Tagname  :" << _tagName << endl;
  cout << "Tagvalue :" << _tagValue << endl;
  for (int i= 0; i < (int)_attributes.size(); i++)
  {
      cout << "Attribute " << i << " : Name : "<< _attributes.at(i)._attributeName << " Value : " << _attributes.at(i)._attributeValue << endl;
  }
}
 
// set the main set details value
void xmlObject::setXmlMainDetails(bool value)
{	
    _xmlMainDetails = value;
}
 
// get a boolean value to see if the xmlObject is the main <?xml .. ?> value
bool xmlObject::getXmlMainDetails()
{
  return _xmlMainDetails;
}
 
 
/*xmlReader*/
xmlReader::xmlReader()
{
}
 
// attribute is normally in the format of attributeName="attributeValue"
xmlAttribute xmlReader::getAttribute(string attributeString)
{
  xmlAttribute returnAttribute;
 
  // make sure that there is a = in the attribute string
  int findEqual = attributeString.find('=');
  if (findEqual > 0)
  {
    // set the attribute name to the substring till the equal
    returnAttribute._attributeName = attributeString.substr(0,findEqual);
    // make sure that there is some characters after the '=' sign.
    if (attributeString.length() > (findEqual+3))
    {
      returnAttribute._attributeValue = attributeString.substr(findEqual+2,(attributeString.length() - (findEqual +3)));
    }
    else
      throw BADATTRIBUTE;
  }else
    // if there does not appear to be ="" at the end of the string then throw a error.
    throw BADATTRIBUTE;
 
  return returnAttribute;
}
 
vector<xmlAttribute> xmlReader::getAttributesFromString(string str)
{
    vector<xmlAttribute> returnAtt;
    xmlAttribute attribute;
    int args;
    char st1[CHARACTERLENGHT];
 
    // args normally equals 1 because there is a attribute present
    // else there was no attribute there, just do one at a time
    args = sscanf(str.c_str(), "%s", st1);
    while (args  == 1 && (str.length() > 1)) {
      // see if there is a real attribute attributeName="attributeValue"
      try {
	attribute = getAttribute(st1);
	// push back in the vector array the attribute
	returnAtt.push_back(attribute);
      } catch (string errorStr)		// any errors
      {
	cout << "ERROR : " << errorStr << endl;
      }
      // re-do the string to pull out any more attributes.
      str = str.substr(strlen(st1));
      // see if there is any more attributes present.
      args = sscanf(str.c_str(), "%s", st1);
    }
    return returnAtt;
}
 
// scan through the xml string and pull out the tags and the attributes and value.
xmlObject xmlReader::readLine(string xmlToSplitUp, string* tagName)
{
  xmlObject returnObj;
  string returnLine, value, endTagName;
  int findXml;
 
  // pick out the tag name, if none then return and throw a bad tag name error.
  *tagName = readUntilCharacter(xmlToSplitUp, '<','>', &returnLine);
  if (tagName->length() ==0)
  {
     throw BADTAGNAME;
     return returnObj;
  }
 
  // if there is a xml version etc in the tagname then process the xml version encoding values.
  findXml=tagName->find("xml");
  if ((findXml > 0 && findXml < tagName->length()) && tagName->length() > 1 )
  {
    // this is the xml version etc.
    // there should be ? at each end of the xml version statement
    string xmlStr = readUntilCharacter(*tagName, '?','?', &returnLine);
    if (returnLine != "?") 
    {
      throw BADXMLVERSION;
      return returnObj;
    }
    // go passed the xml characters.
    returnLine = xmlStr.substr(findXml+3);
    // read any of the attributes from the string
    returnObj.setAttributeVector(getAttributesFromString(returnLine));
    // I am storing the version and any other xml details, so set the return value to store in the correct place.
    returnObj.setXmlMainDetails(true);
  }else if (tagName->length() > 1) 
  {
    // need to see if there is any attributes
    int findTagAtts = tagName->find(' ');
    if (findTagAtts < tagName->length())
    {
      // the attributes are passed the space character in the tagName variable
      string attributes = tagName->substr(findTagAtts);
      // store only the tagName in the tagName variable since pulled out the attributes
      *tagName = tagName->substr(0,findTagAtts);
      // get the attributes into a vector and store in the return object
      returnObj.setAttributeVector(getAttributesFromString(attributes));
    }
 
    if (returnLine.length() > 1)
    {
      // pull out the value in the xml line <tagname>VALUE</tagname>
      value = readUntilCharacter(returnLine,'>','<',&returnLine);
      returnObj.setTagValue(value);
    }
    if (returnLine.length() > 1)
    {
      // pick out the end tag name and make sure it is the same as the first one.
      endTagName = readUntilCharacter(returnLine,'<','>',&returnLine);
      string compareEndTag = "/"+*tagName;
      //if the end tag is not the same as the tag name then throw a error.
      if (endTagName != compareEndTag) 
      {
	throw BADXMLTAGEND;
      } 
    }
    returnObj.setTagName(*tagName);
 
   }
  return returnObj;
}
 
// pick out the characters between two character points, and also return the rest of the line.
string xmlReader::readUntilCharacter(string line, char characterStart, char characterEnd, string *returnLine)
{
  string returnString;
  // find the first occurrence of the character integer placement
  int firstChar = line.find(characterStart);
  // if there is one.
  if (firstChar >= 0)
  {
    // setup the return string, even if a second part cannot be found.
    returnString = line.substr(firstChar+1, (line.length()- firstChar)-1);
    int secChar = returnString.find(characterEnd);
    //if the secound part can be found
    if (secChar > 0)
    {
      *returnLine = returnString.substr(secChar, (returnString.length() - secChar));
      returnString = returnString.substr(0,secChar);
    }
  }
  return returnString;
}
 
// read in the XML file and place each line into the vector xmlObject 
bool xmlReader::loadFile(string filename)
{
  xmlObject xmlObj;
  string line, tagName;
 
  ifstream xmlfile(filename.c_str());
  if (xmlfile.is_open())
  {
      // if the xml version and also the encodingvalues are present.
      //getline(xmlfile,line);
 
      while (!xmlfile.eof())
      {
	  // pull out the start tag and compare against the endtag
	  getline(xmlfile,line);
	  try 
	  {
	    // pick out the xml details from line and return a xmlObject 
	    // to add to the vector array of xml objects
	    // also return the tagName if any futher processing is required.
	    xmlObj = readLine(line, &tagName);
	    // if there is ?xml version etc details present store, else store into the main xml details
	    if (xmlObj.getXmlMainDetails())
	    {
	      _xmlMainDetails.push_back(xmlObj);
	    }
	    else
	    {  
	      _xmlDetails.push_back(xmlObj);
	    }
	  }
	  // if any error occur during the reading of the xml line.
	  catch (string errorStr)
	  {
	    cout << "ERROR : " << errorStr << endl;
	  }
      }
 
      xmlfile.close();
  }
  else
  {
      cout << "Unable to open the file" << endl;
  }
}
 
/* print Out the outer XML values */
void xmlReader::printOuterXML()
{
    cout << "XML Reader Main Object (Xml main details) " << endl;
    for (int i =0; i < _xmlMainDetails.size(); i++)
      _xmlMainDetails.at(i).printOutXmlObject();
 
    cout << "XML Reader xml details" << endl;
    for (int i =0; i < _xmlDetails.size(); i++)
      _xmlDetails.at(i).printOutXmlObject();
}

Xml reader – cpp

The xml reader from the xmlreader in cpp joins together the xmlattribute and xmlobject and this last class, this one is the biggest because it does most of the work. So shall try and explain each part.

As before a xml is

<tagname attributesname="attributesvalue">value</tagname>

The main structure includes the xml definition ( ) in the _xmlMainDetails and the rest of the xml file is in _xmlDetails vectors of xmlObject.

The main file is loaded with the loadLoad ( filename ) and then printout the xml that has been loaded, shall have to do some more public functions to view etc the loaded xml file, but this is just the basics of a xml reader. The rest are private functions because they will load the xml file in the _xmlDetails variable.

class xmlReader {
  protected:
    vector<xmlObject> _xmlMainDetails;
    vector<xmlObject> _xmlDetails;
 
  public: 
    xmlReader();
 
    // open file and read in the xml file and place into the _xmlDetails
    bool loadFile(string filename);
    void printOuterXML();
 
  private :
    xmlObject readLine(string xmlToSplitUp, string* tagName);
    string readUntilCharacter(string line, char characterStart, char characterEnd, string *returnLine);
    xmlAttribute getAttribute(string attributeString);
    vector<xmlAttribute> getAttributesFromString(string str);
};

The BADATTRIBUTE are const string values that I have included at the bottom, but they are within a try {} catch {} code, so that it will throw a error to be catch.

The getAttribute, will try and obtain the attribute from a string parameter, e.g. if the string parameter is in the style of attributename=”attributevalue”, then it will store the name and value in the xmlAttribute to return back to the calling method.

/*xmlReader*/
xmlReader::xmlReader()
{
}
 
// attribute is normally in the format of attributeName="attributeValue"
xmlAttribute xmlReader::getAttribute(string attributeString)
{
  xmlAttribute returnAttribute;
 
  // make sure that there is a = in the attribute string
  int findEqual = attributeString.find('=');
  if (findEqual > 0)
  {
    // set the attribute name to the substring till the equal
    returnAttribute._attributeName = attributeString.substr(0,findEqual);
    // make sure that there is some characters after the '=' sign.
    if (attributeString.length() > (findEqual+3))
    {
      returnAttribute._attributeValue = attributeString.substr(findEqual+2,(attributeString.length() - (findEqual +3)));
    }
    else
      throw BADATTRIBUTE;
  }else
    // if there does not appear to be ="" at the end of the string then throw a error.
    throw BADATTRIBUTE;
 
  return returnAttribute;
}

The getAttributesFromString if there are 0-x amount of attributes within a string it will process each one in turn and request the above method getAttributes to actually fill in the xmlAttribute variable.

vector<xmlAttribute> xmlReader::getAttributesFromString(string str)
{
    vector<xmlAttribute> returnAtt;
    xmlAttribute attribute;
    int args;
    char st1[CHARACTERLENGHT];
 
    // args normally equals 1 because there is a attribute present
    // else there was no attribute there, just do one at a time
    args = sscanf(str.c_str(), "%s", st1);
    while (args  == 1 && (str.length() > 1)) {
      // see if there is a real attribute attributeName="attributeValue"
      try {
	attribute = getAttribute(st1);
	// push back in the vector array the attribute
	returnAtt.push_back(attribute);
      } catch (string errorStr)		// any errors
      {
	cout << "ERROR : " << errorStr << endl;
      }
      // re-do the string to pull out any more attributes.
      str = str.substr(strlen(st1));
      // see if there is any more attributes present.
      args = sscanf(str.c_str(), "%s", st1);
    }
    return returnAtt;
}

readLine, is the main part of the xml reading object. Here is the basics of what this class is doing.

If there is no tagname within a xml line, return.

If the xml line is the main definition process that style of xml line input, and pull out any attributes that are present.

Else process a normal xml line input with attributes (if present) get the value of the tag and then check to make sure that the end tag name is the same as the first tagname.

// scan through the xml string and pull out the tags and the attributes and value.
xmlObject xmlReader::readLine(string xmlToSplitUp, string* tagName)
{
  xmlObject returnObj;
  string returnLine, value, endTagName;
  int findXml;
 
  // pick out the tag name, if none then return and throw a bad tag name error.
  *tagName = readUntilCharacter(xmlToSplitUp, '<','>', &returnLine);
  if (tagName->length() ==0)
  {
     throw BADTAGNAME;
     return returnObj;
  }
 
  // if there is a xml version etc in the tagname then process the xml version encoding values.
  findXml=tagName->find("xml");
  if ((findXml > 0 && findXml < tagName->length()) && tagName->length() > 1 )
  {
    // this is the xml version etc.
    // there should be ? at each end of the xml version statement
    string xmlStr = readUntilCharacter(*tagName, '?','?', &returnLine);
    if (returnLine != "?") 
    {
      throw BADXMLVERSION;
      return returnObj;
    }
    // go passed the xml characters.
    returnLine = xmlStr.substr(findXml+3);
    // read any of the attributes from the string
    returnObj.setAttributeVector(getAttributesFromString(returnLine));
    // I am storing the version and any other xml details, so set the return value to store in the correct place.
    returnObj.setXmlMainDetails(true);
  }else if (tagName->length() > 1) 
  {
    // need to see if there is any attributes
    int findTagAtts = tagName->find(' ');
    if (findTagAtts < tagName->length())
    {
      // the attributes are passed the space character in the tagName variable
      string attributes = tagName->substr(findTagAtts);
      // store only the tagName in the tagName variable since pulled out the attributes
      *tagName = tagName->substr(0,findTagAtts);
      // get the attributes into a vector and store in the return object
      returnObj.setAttributeVector(getAttributesFromString(attributes));
    }
 
    if (returnLine.length() > 1)
    {
      // pull out the value in the xml line <tagname>VALUE</tagname>
      value = readUntilCharacter(returnLine,'>','<',&returnLine);
      returnObj.setTagValue(value);
    }
    if (returnLine.length() > 1)
    {
      // pick out the end tag name and make sure it is the same as the first one.
      endTagName = readUntilCharacter(returnLine,'<','>',&returnLine);
      string compareEndTag = "/"+*tagName;
      //if the end tag is not the same as the tag name then throw a error.
      if (endTagName != compareEndTag) 
      {
	throw BADXMLTAGEND;
      } 
    }
    returnObj.setTagName(*tagName);
 
   }
  return returnObj;
}

readUntilCharacter, is to pick out a string between two character points e.g. string = “a place to run to, here is it, codingfriends.com” and you want to pick out “here is it” there is two ‘,’ each side of it. So to pull out the readUntilCharacter(“a place to run to, here is it, codingfriends.com”, ‘,’ , ‘,’ , &returnLine) the returnLine is the rest of the line after the last character searched for.

// pick out the characters between two character points, and also return the rest of the line.
string xmlReader::readUntilCharacter(string line, char characterStart, char characterEnd, string *returnLine)
{
  string returnString;
  // find the first occurrence of the character integer placement
  int firstChar = line.find(characterStart);
  // if there is one.
  if (firstChar >= 0)
  {
    // setup the return string, even if a second part cannot be found.
    returnString = line.substr(firstChar+1, (line.length()- firstChar)-1);
    int secChar = returnString.find(characterEnd);
    //if the secound part can be found
    if (secChar > 0)
    {
      *returnLine = returnString.substr(secChar, (returnString.length() - secChar));
      returnString = returnString.substr(0,secChar);
    }
  }
  return returnString;
}

loadFile will load the xml file into the private _xmlMainDetails and _xmlDetails and just see’s if file is present and try’s to load it.

// read in the XML file and place each line into the vector xmlObject 
bool xmlReader::loadFile(string filename)
{
  xmlObject xmlObj;
  string line, tagName;
 
  ifstream xmlfile(filename.c_str());
  if (xmlfile.is_open())
  {
      // if the xml version and also the encodingvalues are present.    
      while (!xmlfile.eof())
      {
	  // pull out the start tag and compare against the endtag
	  getline(xmlfile,line);
	  try 
	  {
	    // pick out the xml details from line and return a xmlObject 
	    // to add to the vector array of xml objects
	    // also return the tagName if any futher processing is required.
	    xmlObj = readLine(line, &tagName);
	    // if there is ?xml version etc details present store, else store into the main xml details
	    if (xmlObj.getXmlMainDetails())
	    {
	      _xmlMainDetails.push_back(xmlObj);
	    }
	    else
	    {  
	      _xmlDetails.push_back(xmlObj);
	    }
	  }
	  // if any error occur during the reading of the xml line.
	  catch (string errorStr)
	  {
	    cout << "ERROR : " << errorStr << endl;
	  }
      }
 
      xmlfile.close();
  }
  else
  {
      cout << "Unable to open the file" << endl;
  }
}

Will print out the xml loaded from the xml file.

/* print Out the outer XML values */
void xmlReader::printOuterXML()
{
    cout << "XML Reader Main Object (Xml main details) " << endl;
    for (int i =0; i < _xmlMainDetails.size(); i++)
      _xmlMainDetails.at(i).printOutXmlObject();
 
    cout << "XML Reader xml details" << endl;
    for (int i =0; i < _xmlDetails.size(); i++)
      _xmlDetails.at(i).printOutXmlObject();
}

here are the constant string values.

const int CHARACTERLENGHT = 80;
const string BADXMLVERSION = "Xml version - first line ? - problem";
const string BADTAGNAME = "Tag name was not present";
const string BADXMLTAGEND = "End tag is not the same as tag name";
const string BADATTRIBUTE = "Attribute in wrong format attributeName=\"attributeValue\"";

Xml object – c++

From the main project xmlreader, here is the xml object that I created to have a xml line of code which holds the details of a basic xml.

The main basics of a xml are as below

<tagname attributesname="attributesvalue">value</tagname>

So I will need to store the tagname, attributes and the value. Here is the class structure that I did come up with.

class xmlObject {
  private :
    string _tagName, _tagValue;
    vector<xmlAttribute> _attributes;
    bool _xmlMainDetails;
 
  public:
      xmlObject() { _xmlMainDetails = false;} ;
      xmlObject(string tag, string tValue, xmlAttribute attribute);
 
      void setTagName(string tagName);
      void setTagValue(string tagValue);
      void addAttributes(xmlAttribute attribute);
      void setAttributeVector(vector<xmlAttribute> setAtt);
      void setXmlMainDetails(bool value);
      bool getXmlMainDetails();
      void printOutXmlObject();
};

The set/getXmlMainDetails are if the are at the top of the xml file and need to store them in a different place.

A vector is a nice array basically, it allows to dynamically increment the size of the array with using the push_back (and the opposite to shrink pop_back).

The basics of a vector are as below, means to have a vector of type int

vector<int> intvector;

Here is the class implementation of the object structure xmlObject

/* xmlObject */
// constructor for xmlObject, if any details are passed whilst constructing 
xmlObject::xmlObject(string tag, string tValue, xmlAttribute attribute)
{
  _tagName = tag;
  _tagValue = tValue;
  _attributes.push_back(attribute);
}
 
// xml <tagname attributes="attributesvalue">VALUE</tagname>
// set the tag name
void xmlObject::setTagName(string tagName)
{
  _tagName = tagName;
}
 
// set tag value
void xmlObject::setTagValue(string tagValue)
{
  _tagValue = tagValue;
}
 
// add attributes to the vector attributes variable
void xmlObject::addAttributes(xmlAttribute attribute)
{
  _attributes.push_back(attribute);
}
 
// fill in the vector attributes variable.
void xmlObject::setAttributeVector(vector<xmlAttribute> setAtt)
{
  _attributes = setAtt;
}
 
// print out the xml object detais, with the attributes values.
void xmlObject::printOutXmlObject()
{
  cout << "XML Object" << endl;
  cout << "Tagname  :" << _tagName << endl;
  cout << "Tagvalue :" << _tagValue << endl;
  for (int i= 0; i < (int)_attributes.size(); i++)
  {
      cout << "Attribute " << i << " : Name : "<< _attributes.at(i)._attributeName << " Value : " << _attributes.at(i)._attributeValue << endl;
  }
}
 
// set the main set details value
void xmlObject::setXmlMainDetails(bool value)
{	
    _xmlMainDetails = value;
}
 
// get a boolean value to see if the xmlObject is the main <?xml .. ?> value
bool xmlObject::getXmlMainDetails()
{
  return _xmlMainDetails;
}

I shall post on how to implement/compile etc a class in two different files later on, in a lessons basics for different languages but on the whole, if you store the top structure in a .h header file and then the implementation in a .cpp file. Of course shall post the whole code to store in .h .cpp files accordlying for the whole project but this is just a stripped down version.

Xml Attributes – c++

I am doing the project xml reader in cpp and here is the start. The main project is xmlreader which will have links to the 3 different parts of the xml reader object that I have created.

The basics of xml are

<tagname attributesName="attributesValue">value</tagname>

there can be 0-n amount of attributes in the XML.

So to start with I have created a basic structure for a xmlAttribute and here it is

struct xmlAttribute {
    string _attributeName, _attributeValue;
};

a structure is a very basic object that has x amount of parts to it.

The next is a xml object that will have 0-x amount of xmlAttributes, there should be a link at the top right to the next xml object class.

Delegates – csharp

A delegate, is how to reference a method, something like function pointer in c++. One of the main questions of why is there a delegate/function pointer, it is because it gives the developer/user maximum amount of flexibility, lets say that you have a list of functions that you want to call if someone passes you there name and these functions could be, join together with surname, add in there ID code to there class and some other functions at the users decision like what is there car registration etc. well a delegate/function pointer can allow for different methods be called without having a set process at compile time. You could take path a , b or even c. It is harder to test with sometimes, but as long as the test process has a line to follow as well then things are good.

The delegate syntax is like other methods apart from the operative word delegate is just before the return type and there is no code within the body, it is more of a skeleton of a method/function and return type.

Here is the basic delegate syntax.

public delegate int Compare(object object1, object object2);

I have included this within the code below, what the code does is to create 5 names, and there is a sort to order the names with the returned value from the compared method/function (bubble sort). But the Compare function could be changed to order A-Z, Z-A etc.. since you can have different Compare’s methods coded but just alter one line of code to call the new method/function.

Compare compare = new Compare(SimpleDelegateName.CompareNames);

that one.

Anyway, hope that the code/comments make sense and also help to give reasons for the delegate and how it is useful.

using System;
 
namespace SimpleDelegate
{
	// setup a basic delegate to compare two objects.
	// return values = 0 (same), 1 (object1 > object2), -1 (object1 < object2)
	public delegate int Compare(object object1, object object2);
 
	class SimpleDelegateName 
	{
		// has to be a static otherwise when you try to create a instance of Compare (the delegate)
		// it will not have anywhere to point to, since static means create method even if not creating
		// the object
		public static int CompareNames(object obj1, object obj2)
		{
			// conver the objects into strings
			string name1 = obj1.ToString();
			string name2 = obj2.ToString();
 
			if (String.Compare(name2,name1) > 0)
			{
				return 1;
			} else if (String.Compare(name2, name1) < 0)
			{
				return -1;
			} else 
			{
				return 0;
			}
		}
 
		public SimpleDelegateName() 
		{
			name = "";
		}
 
		public SimpleDelegateName(String pName)
		{
			name = pName;
		}
 
		public String returnName()
		{
			return name;
		}
 
		private String name;
	}
 
	class MainClass
	{
		public static void Main(string[] args)
		{
			// create 5 names
			SimpleDelegateName[] names = new SimpleDelegateName[5];
			names[0] = new SimpleDelegateName("Ian");
			names[1] = new SimpleDelegateName("John");
			names[2] = new SimpleDelegateName("Alice");
			names[3] = new SimpleDelegateName("Tom");
			names[4] = new SimpleDelegateName("Katie");
			// they are no pictular order.
 
			// the delegate instance varibale
			// create a new compare object with the CompareNames method within the SimpleDeleteName class
			Compare compare = new Compare(SimpleDelegateName.CompareNames);
 
			// the basic bubble sort, moves 1 word at a time up/down the array
			object temp;
			for (int i = 0; i < names.Length; i++)
			{
				for (int j = 0; j < names.Length; j++)
				{
					Console.WriteLine("DEBUG : i = " + i + " j = " + j 
					                   + " name 1 =  " + names[i].returnName() + " name 2 = " + names[j].returnName() 
					                  	+ " compare " + compare(names[i].returnName(), names[j].returnName()));
					// if the names[i] is greater than names[j] then swap the names around.
					if (compare(names[i].returnName(), names[j].returnName()) >0)
					{
						Console.WriteLine("DEBUG : " +names[i].returnName() + "   " + names[j].returnName());
						temp = names[i];
						names[i] = names[j];
						names[j] = (SimpleDelegateName)temp;
						// swapped..
						Console.WriteLine("DEBUG : " +names[i].returnName() + "   " + names[j].returnName() + " SWAPPED");
					}
				}
			}
 
			// print out the names in alphabetical order
			foreach (SimpleDelegateName n in names)
			{
				Console.WriteLine("Name : " + n.returnName());
			}
		}
	}
}
DEBUG : i = 0 j = 0 name 1 =  Ian name 2 = Ian compare 0
DEBUG : i = 0 j = 1 name 1 =  Ian name 2 = John compare 1
DEBUG : Ian   John
DEBUG : John   Ian SWAPPED
DEBUG : i = 0 j = 2 name 1 =  John name 2 = Alice compare -1
DEBUG : i = 0 j = 3 name 1 =  John name 2 = Tom compare 1
DEBUG : John   Tom
DEBUG : Tom   John SWAPPED
DEBUG : i = 0 j = 4 name 1 =  Tom name 2 = Katie compare -1
DEBUG : i = 1 j = 0 name 1 =  Ian name 2 = Tom compare 1
DEBUG : Ian   Tom
DEBUG : Tom   Ian SWAPPED
DEBUG : i = 1 j = 1 name 1 =  Tom name 2 = Tom compare 0
DEBUG : i = 1 j = 2 name 1 =  Tom name 2 = Alice compare -1
DEBUG : i = 1 j = 3 name 1 =  Tom name 2 = John compare -1
DEBUG : i = 1 j = 4 name 1 =  Tom name 2 = Katie compare -1
DEBUG : i = 2 j = 0 name 1 =  Alice name 2 = Ian compare 1
DEBUG : Alice   Ian
DEBUG : Ian   Alice SWAPPED
DEBUG : i = 2 j = 1 name 1 =  Ian name 2 = Tom compare 1
DEBUG : Ian   Tom
DEBUG : Tom   Ian SWAPPED
DEBUG : i = 2 j = 2 name 1 =  Tom name 2 = Tom compare 0
DEBUG : i = 2 j = 3 name 1 =  Tom name 2 = John compare -1
DEBUG : i = 2 j = 4 name 1 =  Tom name 2 = Katie compare -1
DEBUG : i = 3 j = 0 name 1 =  John name 2 = Alice compare -1
DEBUG : i = 3 j = 1 name 1 =  John name 2 = Ian compare -1
DEBUG : i = 3 j = 2 name 1 =  John name 2 = Tom compare 1
DEBUG : John   Tom
DEBUG : Tom   John SWAPPED
DEBUG : i = 3 j = 3 name 1 =  Tom name 2 = Tom compare 0
DEBUG : i = 3 j = 4 name 1 =  Tom name 2 = Katie compare -1
DEBUG : i = 4 j = 0 name 1 =  Katie name 2 = Alice compare -1
DEBUG : i = 4 j = 1 name 1 =  Katie name 2 = Ian compare -1
DEBUG : i = 4 j = 2 name 1 =  Katie name 2 = John compare -1
DEBUG : i = 4 j = 3 name 1 =  Katie name 2 = Tom compare 1
DEBUG : Katie   Tom
DEBUG : Tom   Katie SWAPPED
DEBUG : i = 4 j = 4 name 1 =  Tom name 2 = Tom compare 0
Name : Alice
Name : Ian
Name : John
Name : Katie
Name : Tom

Overrideing polymorphism – c#

Overrideing is also similar to overloading (sometimes it can be called the same thing since you are overloading/polymorphism functions and classes).

Polymorphism is when you implement functions that are defined in the base class, overriding is when you over ride a base class function.

But with Overrideing classes in c# you can override functions from the base class that are declared as virtual. Virtual means that they are capable of being overridden in a inherited class, so that incase someone tries to call a method of a same name in a subclass then the base class is still called e.g. sometimes better using code and output to show more than what words can say.

Here is not using the virtual keyword in the base class, so that when you try to call the subclasses same method it still goes to the base class.

using System;
 
namespace polymorphism
{
	class Shape {
		public void printName()
		{
			Console.WriteLine("Shape base class");
		}
	}
 
	class Circle : Shape {
		public new void printName()
		{
			Console.WriteLine("Circle class");
		}
	}
 
	class Rectangle : Shape {
		public new void printName()
		{
			Console.WriteLine("Rectangle class");
		}
	}
 
	class Line : Shape {
		public new void printName()
		{
			Console.WriteLine("Line class");
		}
	}
 
	class MainClass
	{
		public static void Main(string[] args)
		{
			Shape[] shapesArray = new Shape[4];
			shapesArray[0] = new Shape();
			shapesArray[1] = new Circle();
			shapesArray[2] = new Rectangle();
			shapesArray[3] = new Line();
 
			foreach (Shape shape in shapesArray)
			{
				shape.printName();
			}
		}
	}
}

output would

Shape base class
Shape base class
Shape base class
Shape base class

but with the

virtual -  override

keywords.

The code

using System;
 
namespace polymorphism
{ 
	class Shape {
		public virtual void printName()
		{
			Console.WriteLine("Shape base class");
		}
	}
 
	class Circle : Shape {
		public override void printName()
		{
			Console.WriteLine("Circle class");
		}
	}
 
	class Rectangle : Shape {
		public override  void printName()
		{
			Console.WriteLine("Rectangle class");
		}
	}
 
	class Line : Shape {
		public override  void printName()
		{
			Console.WriteLine("Line class");
		}
	}
 
	class MainClass
	{
		public static void Main(string[] args)
		{
			Shape[] shapesArray = new Shape[4];
			shapesArray[0] = new Shape();
			shapesArray[1] = new Circle();
			shapesArray[2] = new Rectangle();
			shapesArray[3] = new Line();
 
			foreach (Shape shape in shapesArray)
			{
				shape.printName();
			}
		}
	}
}

As expected the printName() function was called from the subclasses, because of the virtual keyword.

Shape base class
Circle class
Rectangle class
Line class