Click here to Skip to main content
12,510,403 members (49,337 online)
Click here to Skip to main content
Add your own
alternative version

Stats

200.3K views
2.8K downloads
58 bookmarked
Posted

Object-oriented XML Parser

, 28 Aug 2001
Rate this:
Please Sign up or sign in to vote.
Object-oriented parser to read/write XML files using MSXML parser

Introduction

I had a task to write an XML parser to read/write XML files with list of possibilities (requirements).

Requirements:

  • Comfort for developer (user of parser)
  • Possibility of recording and reading using the same instance of parser
  • No use of MFC
  • User object writes and reads itself
  • Possibility to write in binary stream, without changing source of user objects
  • Possibility of creation of proxy classes for reading/writing of user classes, modification of which is forbidden
  • Same code in user object for reading and writing
  • Possibility of reading/writing simple types
  • Possibility of reading/writing objects (with possibility of determination of type during loading)
  • Possibility of reading/writing vector, map of simple and complex objects
  • Possibility of reading/writing the attributes
  • Absences of restrictions on nesting of one type in others
  • Minimization of operations "if"
  • Unimportance of order of tags in parent tag
  • Absence of support namespace and schema

Solution

Based on several ideas:

  1. Using of parser-a based on sample from Windows Platform SDK
  2. Each user object that understand that it is his time to be read, throws itself just like "throw this"
  3. Than parser catch him and put into stack and all calls will be send to this object, until anyone else throw itself or end of object will be found
  4. Each user object have only one function "determine(ProxyObject& proxy)" it should ovewrite
  5. Proxy - it is an abstract object that have some virtual functions to read/write some types of data and proxy implementations which are made automaticaly by parser to exactly "know" the type of stream and current operation
  6. There is a template class with template constructor, that gets members of user objects, proxy object, "name" of the object to read
  7. This template class understands itself what to do with that members and call corresponding proxy's functions.
  8. There are some proxy classes that can read/write string, int and float.

Here is that wonderful template:

template <class T = void*>
class determineMember
{
    public:
    template <class OT>
    determineMember(OT& t, 
        const char* str,XmlParserProxy& p,T* _t=0) throw(XmlObject*)
    {
        determine(t,str,p,_t,type(t));
    }
};

Currently my parser satisfies all requirements above. And this is example of user objects:

struct Nodes : XmlObject
{
    vectorDel<Node*>  m_nodes;
    virtual void determine(XmlParserProxy& p) throw(XmlObject*)
    {
        determineMember<StartNode>(m_nodes,"start-node",p);
        determineMember<InteractionNode>(m_nodes,"interaction-node",p);
    }
};
struct Pipeline : XmlObject
{
  string m_name;
  int    m_count;
  float  m_sum;
  SomeObject* m_someObject;
  vector<string> m_transitions;
  vector<int> m_point;
  Nodes m_nodes;
  map<int,NodeDisplay> m_map;
  virtual void determine(XmlParserProxy& p) throw(XmlObject*)
  {
    determineMember<>(m_name,"name",p);
    determineMember<>(m_count,"count",p);
    determineMember<>(m_sum,"sum",p);
    determineMember<FirstObject>(m_someObject,"FirstObject",p);
    determineMember<SecondObject>(m_someObject,"SecondObject",p);
    determineMember<Nodes>(m_nodes,"nodes",p);
    determineMember<string>(m_transitions,"transition",p);
    determineMember<int>(m_point,"point",p);
    determineMember<>(m_map,"Map",p);
  }
};

Note that you can have pointers and vectors of objects and have different classes there.

This is an example of using the parser:

CoInitialize(NULL);

Document doc;
XML::ZXmlParserImpl parser(&doc);

parser.parse(_bstr_t("test.xml"));

parser.save(_bstr_t("saved_test.xml"));

CoUninitialize();

Look at this sample XML file:

<pipeline>
   <!-- string -->
        <name>Default</name>

This table shows how to implement determine function with different members

Member variableSource in determineComments
string m_name;determineMember<>(m_name,"name",p); 
string m_name;determineMember<AtribValue>(m_name,"name",p);Use AtribValue to indicate that name is attribute but not a node
int m_count;determineMember<>(m_name,"count",p); 
float m_sum;determineMember<>(m_name,"sum",p); 
SomeObject* m_someObject;determineMember <FirstObject>(m_someObject, "FirstObject",p);If tag FirstObject found, then new FirstObject will be assigned to m_someObject
SomeObject* m_someObject;determineMember <SecondObject>(m_someObject, "SecondObject",p);If tag SecondObject found, then new SecondObjectwill be assigned to m_someObject
SomeObject m_nodes;determineMember<>(m_nodes,"nodes",p); 
std::vector<int> m_point;determineMember<int>(m_point,"point",p); 
std::vector<string> m_transitions;determineMember <string>(m_transitions, "transition",p); 
std::map<int,SomeObject> m_map;determineMember<>(m_map,"Map",p); 
std::vector<Node*> m_nodesdetermineMember<StartNode>(m_nodes,"start-node",p);If tag start-node found, then new StartNode will be made and inserted in m_nodes
std::vector<Node*> m_nodes;determineMember <InteractionNode>(m_nodes, "interaction-node",p);If tag interaction-node found, then new InteractionNode will be made and inserted in m_nodes

In demo project I have shown how to implement classes for reading/writing std::map not in parser's source files.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Mike Melnikov
Web Developer
Russian Federation Russian Federation
Mike has been programming in C/C++ for 11 years and Visual C++/MFC for 4 years. His background includes pure and applied mathematics, engineering and physics, and he is currently based in Moscow, Russia.

You may also be interested in...

Pro
Pro

Comments and Discussions

 
GeneralCompile errors Pin
Member 6681898-May-08 13:14
memberMember 6681898-May-08 13:14 
QuestionHo do i add MSXMl6.dll to my installer ? Pin
code4jigar5-Sep-06 2:18
membercode4jigar5-Sep-06 2:18 
AnswerRe: Ho do i add MSXMl6.dll to my installer ? Pin
Mike Melnikov29-Sep-06 14:01
memberMike Melnikov29-Sep-06 14:01 
GeneralWriting to an XML file Pin
wcovuaku28-Oct-04 5:56
memberwcovuaku28-Oct-04 5:56 
GeneralRe: Writing to an XML file Pin
Mike Melnikov28-Oct-04 19:07
memberMike Melnikov28-Oct-04 19:07 
QuestionHow to serialize custom map&lt;CString,Object** &gt;? Pin
vgrigor13-Oct-04 22:23
membervgrigor13-Oct-04 22:23 
Generalsome problems: map - error Pin
vgrigor13-Oct-04 20:41
membervgrigor13-Oct-04 20:41 
GeneralHelp please Pin
Anonymous25-Aug-04 22:38
sussAnonymous25-Aug-04 22:38 
GeneralRe: Help please Pin
Colin Angus Mackay25-Aug-04 23:43
memberColin Angus Mackay25-Aug-04 23:43 
GeneralVisual Studio .NET 2003 Pin
Sevig11-Jul-04 20:22
memberSevig11-Jul-04 20:22 
GeneralRe: Visual Studio .NET 2003 Pin
Mike Melnikov25-Aug-04 22:55
memberMike Melnikov25-Aug-04 22:55 
Generallitle trouble with charsets Pin
Alex V. Kayuchkin15-Jan-04 21:47
memberAlex V. Kayuchkin15-Jan-04 21:47 
GeneralRe: litle trouble with charsets Pin
Mike Melnikov15-Jan-04 22:56
memberMike Melnikov15-Jan-04 22:56 
GeneralRe: litle trouble with charsets Pin
aGodInHost1-May-04 5:30
memberaGodInHost1-May-04 5:30 
GeneralProblem with MFC release.. Pin
EPulse21-Dec-03 17:45
memberEPulse21-Dec-03 17:45 
GeneralRe: Problem with MFC release.. Pin
EPulse21-Dec-03 20:52
memberEPulse21-Dec-03 20:52 
GeneralLimitation Pin
Sahbi15-Jun-03 0:45
memberSahbi15-Jun-03 0:45 
GeneralRe: Limitation Pin
Mike Melnikov25-Jun-03 0:49
memberMike Melnikov25-Jun-03 0:49 
Generalabout attribute and one advise Pin
marco.song13-May-03 16:04
membermarco.song13-May-03 16:04 
Generaljust get string, don't save to file. Pin
marco.song10-May-03 8:07
membermarco.song10-May-03 8:07 
GeneralRe: just get string, don't save to file. Pin
Mike Melnikov11-May-03 23:03
memberMike Melnikov11-May-03 23:03 
GeneralRe: just get string, don't save to file. Pin
marco.song13-May-03 15:56
membermarco.song13-May-03 15:56 
GeneralProblem after fixing the memory leaks Pin
Itay Szekely3-Apr-03 5:51
memberItay Szekely3-Apr-03 5:51 
GeneralQuestion about progam flow Pin
Pankaj Kumar7-Jan-03 19:51
memberPankaj Kumar7-Jan-03 19:51 
Questionwhat about header? Pin
gok19-Dec-02 13:40
membergok19-Dec-02 13:40 
GeneralGreat Job :-) Pin
Ram. Sundar13-Nov-02 8:37
memberRam. Sundar13-Nov-02 8:37 
GeneralMemory leaks Pin
Anonymous9-Jul-02 0:28
memberAnonymous9-Jul-02 0:28 
GeneralRe: Memory leaks Pin
John Kirk13-Sep-02 7:39
memberJohn Kirk13-Sep-02 7:39 
GeneralRe: Memory leaks Pin
Anonymous25-May-03 14:06
sussAnonymous25-May-03 14:06 
Generala couple of questions: Pin
Eugene Polonsky8-Jul-02 13:09
memberEugene Polonsky8-Jul-02 13:09 
GeneralRe: a couple of questions: Pin
Mike Melnikov28-Aug-02 21:50
memberMike Melnikov28-Aug-02 21:50 
GeneralExtension for std::list's Pin
Thomas Freudenberg10-Jun-02 2:28
memberThomas Freudenberg10-Jun-02 2:28 
GeneralNice package, but... Pin
Andreas Saurwein27-Feb-02 11:34
memberAndreas Saurwein27-Feb-02 11:34 
GeneralRe: Nice package, but... Pin
Mike Melnikov2-Mar-02 23:58
memberMike Melnikov2-Mar-02 23:58 
GeneralRe: Nice package, but... Pin
Anonymous25-May-03 14:05
sussAnonymous25-May-03 14:05 
GeneralI am using expat to read the xml files, I need to get the value data to display through the web Pin
Anonymous22-Feb-02 14:54
memberAnonymous22-Feb-02 14:54 
QuestionHow to save new struct Pin
DanielVisual5-Sep-01 3:56
memberDanielVisual5-Sep-01 3:56 
AnswerRe: How to save new struct Pin
Mike Melnikov5-Sep-01 4:30
memberMike Melnikov5-Sep-01 4:30 
GeneralThats what I need Pin
Anonymous4-Sep-01 5:01
memberAnonymous4-Sep-01 5:01 
GeneralPlease post a comment Pin
Mike Melnikov30-Aug-01 19:25
memberMike Melnikov30-Aug-01 19:25 
GeneralRe: Please post a comment Pin
Christian Graus30-Aug-01 19:52
memberChristian Graus30-Aug-01 19:52 
GeneralRe: Please post a comment Pin
Mike Melnikov5-Sep-01 4:24
memberMike Melnikov5-Sep-01 4:24 
GeneralRe: Please post a comment Pin
Anonymous14-Sep-01 5:05
memberAnonymous14-Sep-01 5:05 
GeneralRe: Please post a comment Pin
Anonymous14-Sep-01 5:06
memberAnonymous14-Sep-01 5:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.160929.1 | Last Updated 29 Aug 2001
Article Copyright 2001 by Mike Melnikov
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid