Click here to Skip to main content
Click here to Skip to main content

Object-oriented XML Parser

By , 28 Aug 2001
 

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>
        <!-- int -->
         <count>2</count>
        <!-- float -->
         <sum>1.234567</sum>
        <!-- object having type from set of types-->
        <SecondObject>
          <second>1</second>
        </SecondObject>
         <!-- uncomment FirstObject and comment SecondObject 
                     to make FirstObject instead of SecondObject
        <FirstObject>
          <first>1</first>
        </FirstObject>
        -->
        <!-- new XMLObject of type Nodes-->
        <nodes>
                <!-- insert in vector<Node> new StartNode, 
                                               string attribute-->
                <start-node id="Start">
                        <!-- insert vector<NodeDisplay> new NodeDisplay-->
                        <node-display>
                <x-center>0</x-center>
                <y-center>0</y-center>
            </node-display>
            <node-display>
                                <x-center>1</x-center>
                                <y-center>1</y-center>
            </node-display>
        </start-node>
                <!-- insert in vector<Node> 
                        new InteractionNode, string attribute-->
                <interaction-node id="It">

                    <!-- two string attributes-->
                   <template dynamic="false" index="2">
                           testS
                   </template>
                </interaction-node>
    </nodes>

<!-- vector of strings -->
        <transition>Tr1</transition>
        <transition>Tr2</transition>

<!-- vector of ints -->
        <point>3</point>
        <point>2</point>
        <point>1</point>

<!-- and now - std::map<int,NodeDisplay> -->
        <Map>
          <pair>
            <name>1</name>
            <value>
                <x-center>1</x-center>
                <y-center>2</y-center>
            </value>
          </pair>
          <pair>
            <name>2</name>
            <value>
                <x-center>4</x-center>
                <y-center>3</y-center>
            </value>
          </pair>
        </Map>

</pipeline>

This table shows how to implement determine function with different members

Member variable Source in determine Comments
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_nodes determineMember<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

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.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralCompile errorsmemberMember 6681898-May-08 13:14 
I tried to compile the project file and got errors
 

Linking...
LINK : fatal error LNK1104: cannot open file "msxml2.lib"
Error executing link.exe.
 
xmlparser.exe - 1 error(s), 0 warning(s)
 

Can anybody help?
 
Thanks.
 
Emily
QuestionHo do i add MSXMl6.dll to my installer ?membercode4jigar5-Sep-06 2:18 
I have made an application. Tht requires msxml6. Now, suppose if client does not have msxml 6 installed then what can be done to install it on client machine ?
Please help.....
Since it searches fior the class id for creating instance of the same.
AnswerRe: Ho do i add MSXMl6.dll to my installer ?memberMike Melnikov29-Sep-06 14:01 
mske silence installation of msxml7.msi
 
http://www.microsoft.com/downloads/details.aspx?FamilyID=993C0BCF-3BCF-4009-BE21-27E85E1857B1&displaylang=en
GeneralWriting to an XML filememberwcovuaku28-Oct-04 5:56 
Hi Guys,
I want to write to an xml file in c++. Any ideas will de appreciated!
 
William.
GeneralRe: Writing to an XML filememberMike Melnikov28-Oct-04 19:07 
why not to use my sample?
it can save xml file.

QuestionHow to serialize custom map&lt;CString,Object** &gt;?membervgrigor13-Oct-04 22:23 
If I want to serialize my custom map
like
 
map
 
(problem- with double indirection)
 
How to do it ?
 
Is there some algorithm or advices how to do it ?
 
I see problem - in hardly able overloading same determine Function,
for every vector,
or need to branch on more upper level -write own DetermineMember_vector_custom()function ?
 

 
I think this very good parser must be easily extensible to user's existed containers,
for the sake they do not rewrite existed code,
or convert to only predefined collections simple typing.
 
(PLease see also else question below about map of pointers).
 

Generalsome problems: map - errormembervgrigor13-Oct-04 20:41 
I did found how to use this good package in
cases:
 

class Object
{
virtual determine(..);
};
 
1)vector < Object > vo "vector - with object"
2)map < CString, Object* > mpo "map - with pointer"
 
determindeMember<Object>(vo,"ID", proxy)
determindeMember<Object>(mpo,"ID", proxy)

 
i.e. code made for only restricted set of cases:
 
vector < Object* > //- work with pointers is presented
map < CString, Object > //- is there such a work- with pointers ?
?
 
PLease advice how to implement first two cases?
GeneralHelp pleasesussAnonymous25-Aug-04 22:38 
hi ,
 
Iam using 9 int variables in my code. Instead of it i would like to use binary.Can anyone let me know how to do it
GeneralRe: Help pleasememberColin Angus Mackay25-Aug-04 23:43 
You would be better asking this in the relevant programming forum.
 

"If a man empties his purse into his head, no man can take it away from him, for an investment in knowledge pays the best interest." -- Joseph E. O'Donnell
 
Not getting the response you want from a question asked in an online forum: How to Ask Questions the Smart Way!


GeneralVisual Studio .NET 2003memberSevig11-Jul-04 20:22 
Compiler generetes the error "_check: 'function' : illegal use of explicit template arguments
" in Visual Studio .NET 2003.
 
template
inline bool _check(H* hr)
{
return hr!=0;
}
inline bool _check(bool hr)
{
return hr;
}
 

How will I be able to decide this problem ? Confused | :confused:

GeneralRe: Visual Studio .NET 2003memberMike Melnikov25-Aug-04 22:55 
just remove these 2 functions.
Generallitle trouble with charsetsmemberAlex V. Kayuchkin15-Jan-04 21:47 
Hi, Mike
Realy great parser! Thanx for sharing sources Smile | :)
 
We found a litle problem here:
 
VARIANT_BOOL vBool = m_pIXMLDOMDocument->loadXML(inputStr);
 
in Windows98 this function (MSDN article) works just with 2 character sets (i suppose msxml.dll has an oldest version of this interface Smile | :) . And when i trying to parse CP-1251 encoded document, parser returns error (throw exception, but i do not remember it's description, something like "not supported charset encoding").
 
If i remove MSXML namespace whis MSXML2 (by defining it in precompiled header)
 
#define MSXML MSXML2
 
...it works, but... may be you know better solution?

GeneralRe: litle trouble with charsetsmemberMike Melnikov15-Jan-04 22:56 
Hello Alex.
 
Thank you for your comment.
 
My workaround: I am using utf-8 encoding in all my XML files.
 
Mike.
GeneralRe: litle trouble with charsetsmemberaGodInHost1-May-04 5:30 
Hi Mike
 
Thanx by the share
 
Your code is fine (a little confusing but is fine)
 
Tip: The limitation of charsets is a big deal (I´m brazilian and, in my case, I need to use one charset different than you)
 
Maybe the low score can be given by the existence of more 'popular' xml libraries (Microsoft, dundas, ec ...)
 
I´m, in fact, using the microsoft parser to do this job with relative easy (and this library is common language in the work)
 
Woody
 

GeneralProblem with MFC release..memberEPulse21-Dec-03 17:45 
Hi Mike..
 
Thanx alot for your code..Am using it in an MFC phonebook application..everything was going great (using _DEBUG build) until i tried to run a release build. What happens is like this, when my application tries to save an XML doc to a file it crashes. I I tried to walk through the debug code of the CRT and found that memory alloc. is different for debug and release.
 
void ZXmlParserImpl::do_save()
{
m_proxy = new XMLPrivate::XmlParserProxySave(*this);
m_document->determine(*m_proxy);

 
it crashes inside determine..in the release build the value of this changes while not in the debug build.By the way, there is no problem with the release built of the example code here. so i guess this is something to do with MFC headers. I'd appreciate it if you could check it and post a work-around.
 
Thanx alot..Smile | :)
 

 

 
Time is the best teacher; Unfortunately it kills all it's students!
GeneralRe: Problem with MFC release..memberEPulse21-Dec-03 20:52 
Hi all,
 
It turns out that this problem is related to the compiler settings. This can be fixed by adding the /GR switch to the c/c++ settings in VC or ticking the Enable Run-Time Type Info. option. This is pretty tricky, i got no compile errors, no link errors and no clues in the error message when it crashesWTF | :WTF: .
Hope this will save someone, somewhere, some time Smile | :) .
 
Time is the best teacher; Unfortunately it kills all it's students!
GeneralLimitationmemberSahbi15-Jun-03 0:45 
Sleepy | :zzz: OMG | :OMG: Hi ! Mike
I Like your code because I like templates
really great job !
 
but I've found that it is impossible to implement a 0 or more choice element in an XML file
that has this DTD

<!ELEMENT org ( group* | member*)*>
<!ATTLIST memeber
     type (VIP | EXPERT | NORMAL | GUEST) #REQUIRED
     name CDATA #REQUIRED
     addr CDATA #IMPLIED
     tel   CDATA #REQUIRED
>
<!ELEMENT group ( group* | member*)*>
 

I found it difficult to do without changing your original code
any suggestion please
 

ByeSleepy | :zzz:

 
Sahbi
GeneralRe: LimitationmemberMike Melnikov25-Jun-03 0:49 
Hello Sahbi
 
I am sorry I can't understand the real problem.
can you send me small sample of xml file
and tell what part of it you can't read without modification of code (you can send me it by email)
 
Mike.
Generalabout attribute and one advisemembermarco.song13-May-03 16:04 
When add attributes to the first element, for example, in your sample, I add a attribute to pipeline, when parse, it will throw a exception.
 
I have use your code to my project, but I feel the code which isn't convenient, so I add some macro to my project to use your code.I think add some macro to your project, it will become friendly. for example #define XML_ELEMENT() ....
Generaljust get string, don't save to file.membermarco.song10-May-03 8:07 
I want to get the string which already to save to file. How can I can that? Thanks!!
GeneralRe: just get string, don't save to file.memberMike Melnikov11-May-03 23:03 
ZXmlParser::save has second optional parameter isFile, was not implemented in this article.
 
change function to this :
 

if (SUCCEEDED(createDocument()))
{
do_save();
if(isFile)
m_pIXMLDOMDocument->save(_variant_t(outputStr));
else
outputStr = m_pIXMLDOMDocument->Getxml();
m_pIXMLDOMDocument = 0;
}
 

Mike.
GeneralRe: just get string, don't save to file.membermarco.song13-May-03 15:56 
Thanks for your help.
GeneralProblem after fixing the memory leaksmemberItay Szekely3-Apr-03 5:51 
Hello
 
After fixing the memory leaks as John Kirk posted a few threads below, the map member of the Pipeline (Pipeline::m_map) stopped getting written to saved_test.xml.
The cause is the following change, from:
 
template <class T>
inline void determine(T& t,const char* str,XmlParserProxy& p,void*,common_t)
{
   p.do_member(xmlproxy(t),str);
}
 
To:
 
template <class T>
inline void determine(T& t,const char* str,XmlParserProxy& p,void*,common_t)
{
   XmlObject* pObj = new XMLPrivate::Value2<T>(t);
   p.do_member(*pObj,str);
   delete pObj;
}
 
I couldn't figure out why this happens, perhaps someone could help.
 
TIA,
 
Itay Szekely                                                        
http://come.to/itay
For every action, there is an equal and opposite criticism

GeneralQuestion about progam flowmemberPankaj Kumar7-Jan-03 19:51 
Hi,
 
In the
 
void ZXmlParserImpl::do_save()
{
m_proxy = new XMLPrivate::XmlParserProxySave(*this);
m_document->determine(*m_proxy);
m_curnodes.clear();
}
 
how does m_document (a type of XmlObject) finds out its an object of type Document ? I think then the link is easy to figure out. Document ->
Pipeline.determineMember and then it calls determineMember of its other objects.
 
Even if the question is really dumb, pls do answer Smile | :)
 
Thanks.

Questionwhat about header?membergok19-Dec-02 13:40 
it fails to handle xml header. Eek! | :eek:
GeneralGreat Job :-)memberRam. Sundar13-Nov-02 8:37 
I think you are also using the same code in your 2Find toolbar. I think ppl(atleast me) arent commenting as we already have seen the code in 2Find toolbar Smile | :)
Great job dude!
Keep it up!!!

 
/RamSmile | :)
GeneralMemory leaksmemberAnonymous9-Jul-02 0:28 
Thanks, it's a good job !!
but there are many memory leaks in your app !!
Can you do something for this ??
 
thanks
GeneralRe: Memory leaksmemberJohn Kirk13-Sep-02 7:39 

There are a number of memory leaks dealing with bstr's (which I didn't take the time to track down and fix).   However, many of the other leaks can be fixed by three simple changes:
 
Memory leak 1 (ZXmlParserImpl.h):
 
   namespace XMLPrivate
   {
   . . .
      class XmlParserProxyRead : public XmlParserProxy
      {
         virtual void do_attrib(const char* key, string& str)
            {m_p.do_read_member(*(new Value2<string>(str)),key);}
         // This method always allocates a new 'Value2<string>', but the new object
         // is not always thrown.   In fact, usually it is simply forgotten.
        . . .
      };
   }
 
// Change to...
 
   namespace XMLPrivate
   {
   . . .
      class XmlParserProxyRead : public XmlParserProxy
      {
         virtual void do_attrib(const char* key, string& str)
         {
            XmlObject* pObj = new Value2<string>(str);
            m_p.do_read_member(*pObj,key);
            // If we made it to here, pObj was not thrown.   Clean up.
            delete pObj;
         }
        . . .
      };
   }
 
Memory leak 2 (ZXmlParserImpl.h):
 
inline XmlObject& xmlproxy(string &s) {return *(new XMLPrivate::Value2<string>(s));}
inline XmlObject& xmlproxy(int      &i) {return *(new XMLPrivate::Value2<int>(i));}
inline XmlObject& xmlproxy(float   &i) {return *(new XMLPrivate::Value2<float>(i));}
// ^ These functions always allocate a new object.
. . .
 
template <class T>
inline void determine(T& t,const char* str,XmlParserProxy& p,void*,common_t)
{
   p.do_member(xmlproxy(t),str);
   // ^ Always allocates a new XMLPrivate::Value2<> of some sort.   If the
   //   new object is not thrown by p.do_member(), the object leaks.
}
 
class XmlParserProxyRead : public XmlParserProxy
{
   . . .
   virtual void do_member(XmlObject& t,const char* str) throw(XmlObject*)
      {m_p.do_read_member(t,str);}
   . . .
}
 
void ZXmlParserImpl::do_read_member(XmlObject& t,const char* str) throw(XmlObject*)
{
   if(load()==str)     // If this test is false, t leaks.
      throw &t;
}
 
// Change to...
 
template <class T>
inline void determine(T& t,const char* str,XmlParserProxy& p,void*,common_t)
{
   XmlObject* pObj = new XMLPrivate::Value2<T>(t);
   p.do_member(*pObj,str);
 
   // If we make it to here, pObj was not thrown.   Clean up.
   delete pObj;
}
 
Memory leak 3 (ZXmlParser.cpp):
 
void ZXmlParser::parse(const _bstr_t& strFileName, bool isFile)
{
   XMLNode* hItemRoot = new XMLNode;
   . . .
   print(hItemRoot, "");
   // ^ hItemRoot is allocated, but never freed.
}
 
// Change to...
void ZXmlParser::parse(const _bstr_t& strFileName, bool isFile)
{
   XMLNode* hItemRoot = new XMLNode;
   . . .
   print(hItemRoot, "");
 
   // Clean up.
   delete hItemRoot;
}
 
I hope this helps Smile | :)

 
John Kirk
 
"Man - A figment of God's imagination"   Mark Twain

GeneralRe: Memory leakssussAnonymous25-May-03 14:06 
Hi Mike,
 

What do u think about this changes???
Generala couple of questions:memberEugene Polonsky8-Jul-02 13:09 
Hey Mike:
 
Great job on the class. A couple questions/comments for you:
 
1. Personally, I really like third party classes to be in one .h file. I know it's somewhat... ugly when developing, but I hate having to put someone else's cpp files in my project... well, possibly a personal preference.
 
2. Will this class work if COM is initialized in Multithreaded mode? How about neutral?
 
3. I can't remember for sure, but I seem to recall reading in Effective STL that deriving from a container is a fairly bad idea... anyone else encountered this? I notice you're doing that with vector, just wondering if that might have bad consequences.
 
4. From what I understand of template specialization, you can't define a template function that takes a pointer, and then specialize it to take a base type. Indeed, when I compile your sample with VC.NET, it complains that it can't deduce the bool argument to _check from H* -- it's not picking up the specialization. I changed the H* to H, and tweaked your specialization so it now looks like this:
template<class H> inline bool _check(H hr)
{
  return hr!=0;
}
 
template<> inline bool _check(bool hr)
{
  return hr;
}
 
And that seems to work on VC.NET. (VC.NET supposadly implements more of the C++ standard than VC6... which would explain why VC6 would let it slide...)
Anyway, great job overall.
 
----------------------------------------
----I said my name wasn't important
---------------------------SlartiBartFast
GeneralRe: a couple of questions:memberMike Melnikov28-Aug-02 21:50 
Hello Eugene.
 
Sorry for delay. I just read your message Frown | :(
 
1. .h with .cpp
I guess that you put a lot of YOUR code in .cpp files and that is why don't like to see third party code there. You see, I put my code in .cpp Smile | :)
Without joke, it decreases compilation time.
 
2. Multithreaded mode
yes it is working in my 20 projects in Multithreaded mode. I don't make any CoInitialize in my "library" code.
 
3. deriving from a container
Yes is not good idea, but only for STL, I haven't read that book, but I think I will be near the author, because vector and etc. doesn't have virtual functions, may be some other issues. But I don't make any pointers to that vectors. You can use std::vector instead of vectordel, just don't forget to delete all stored pointers there.
 
4. typename in template
I wrote it to catch any pointer to a class , if _check(H ) work - very well.
 

Mike.
GeneralExtension for std::list'smemberThomas Freudenberg10-Jun-02 2:28 
I really like your approach for XML processing.
 
However, in most cases I prefer std::list to std::vector, therefore I've made following additions to ZXmlParserImpl.h at the given positions:
 
line 175:
struct list_t{};     template <class T> list_t      type(list<T>& )   {return list_t();}
 
line 260:
template <class T,typename NewT>
	inline void determineList(list<T>& ls,const char* str,XmlParserProxy& p,NewT* _t, common_t t_)
{
	if(p.isRead())
	{
		if(p.load()==str)
		{
			ls.push_back(T());
			throw &xmlproxy(*ls.rbegin());
		}
	}
	else
	{
		for (list<T>::iterator it = ls.begin (); it != ls.end(); ++it)
		{
			determine(*ls,str,p,_t,t_);
		}
	}
}
 
template <class T,typename NewT>
	inline void determineList(list<T>& ls,const char* str,XmlParserProxy& p,NewT* _t,Object_t t_)
{
	if(p.isRead())
	{
		if(p.load()==str)
		{
			NewT* node = new NewT();
			ls.push_back(node);
			throw node;
		}
	}
	else
	{
		for (list<T>::iterator it = ls.begin (); it != ls.end(); ++it)
		{
			determine(*it,str,p,_t,ObjectPtr_t());
		}
	}
}
 
template <class T,typename NewT>
	inline void determine(list<T>& ls,const char* str,XmlParserProxy& p,NewT* _t,list_t)
{
	determineList(ls,str,p,_t,type(*_t));
}
 
Your usage of templates really facilitate the extension of your solution Poke tongue | ;-P
 
Regards
Thomas
 
Sonork id: 100.10453 Thömmi
 

Disclaimer:
Because of heavy processing requirements, we are currently using some of your unused brain capacity for backup processing. Please ignore any hallucinations, voices or unusual dreams you may experience. Please avoid concentration-intensive tasks until further notice. Thank you.

GeneralNice package, but...memberAndreas Saurwein27-Feb-02 11:34 
... just a bit more documentation would greatly enhance the use of your otherwise excellent implementation.
I think that its almost impossible for beginners to understand how and why it works.
 
Maybe you could add a more detailed and commented sample to your article?
 
cheers
Andreas
GeneralRe: Nice package, but...memberMike Melnikov2-Mar-02 23:58 
Thank you, Andreas Smile | :)
 
You are right.
 
Yes, I am planning to modify article (make some changes in sources and documentation) and give some more samples. Also I am planning to post one more article with a sample that will show real-life usage of my technology.
 
From another side, as I said in my article, I tried to simplify "clients" (programmers) work, that is why - "server" part (implementation) is enough complex.
 
Mike.
GeneralRe: Nice package, but...sussAnonymous25-May-03 14:05 
If u add some samples and improve a little the documentation ... Sleepy | :zzz: It could beceome a great article!!!
 
I really hope u do it soon ´cause personally I do like the article.
GeneralI am using expat to read the xml files, I need to get the value data to display through the webmemberAnonymous22-Feb-02 14:54 
I am using expat to read the xml files, this is my file
extern char **file(char *);
char html();
int index;
struct elementStruct
{
XML_Char elementData[9];
const XML_Char * elementArray;
const XML_Char ** elementAttr;
};
struct elementStruct EArray[3]={{NULL,"id",NULL},
{NULL,"number",NULL}, {NULL,"title",NULL}}
struct elementStruct EArray[3];
static void startElement(void *userData, const XML_Char *name, const XML_Char **atts){}
static void charHandler(void *userData, const char *s, int len){}
static void endElement(void *userData, const XML_Char *name){}
 
I can able to read the element name, and the all the data in order of xml file.
What I need is to able to read the element 'data' to pass through html form and display to the web using cgi.
Please help me with examle,
Thanks you very much
 
CD

 
cindy
QuestionHow to save new structmemberDanielVisual5-Sep-01 3:56 

Hallo Mike
 
If I load a xml file and change some settings and save the file, it works fine. But how to save a new Document?
Something like that dont work:
 
Document doc;
XML::ZXmlParserImpl parser(&doc);
doc.Pipeline.m_name = "SomeName";
parser.save(FileName);
 
An example would be nice.
 
Thanks in advance.
Daniel

AnswerRe: How to save new structmemberMike Melnikov5-Sep-01 4:30 

Shame on me Frown | :(
 
please add constructor to iniialize Pipeline like this
Pipeline() : m_someObject(0),m_count(0),m_sum(0) {}
 

than your code should work
 
Document doc;
XML::ZXmlParserImpl parser(&doc);
doc.m_pipeline.m_name = "SomeName";
parser.save(_bstr_t("new_test.xml"));
 

Mike
GeneralThats what I needmemberAnonymous4-Sep-01 5:01 
Hallo Mike
 
Good job!
After playing around a little bit, I understand it now.
Its realy easy to use.
 
Thank you fore sharing!Rose | [Rose]
 
Best regards, Daniel
 

GeneralPlease post a commentmemberMike Melnikov30-Aug-01 19:25 
Hi, developers
 
As I can see, most of you don't like my article Frown | :-(
 
But please tell me, why (unuseful, bad programming style, uncommented, undocumented, not understandable, bad english) ?
 
I'll delete it after your explanations.
 
Mike.
GeneralRe: Please post a commentmemberChristian Graus30-Aug-01 19:52 
Mike, I know NOTHING about XML, and haven't looked at your article in depth, but could I just say that:
 
a/ 5 people have voted and the averge vote is 2.8. With such a low number of people voting, one person giving you a 1 because they looked and then decided they don't use XML either would pull your total right down
 
b/ From the glance I gave your article, you have gone into some depth in explaining what you are doing, and it's my opinion that the fact that five people between them decided to mark you low but didn't comment doesn't equate to people hating it. Have a look at some of the REALLY low marked articles to see how quickly people around here present their opinion when it's really in the negative. It looks well written and worthwhile to me.
 
c/ As a result of a project I am involved with I believe I will be doing some XML soonish and when I do I will look up this article, so on a personal level I would prefer to see it remain.
 
I think it should stay and I don't think it's been badly recieved, more that it's been ignored because most of us don't have a use for it. That doesn't mean it's bad, and probably means that the people who need this info will *really* need it.
 
Christian
 
As I learn the innermost secrets of the around me, they reward me in many ways to keep quiet.
 
Men with pierced ears are better prepared for marriage. They've experienced pain and bought Jewellery.
GeneralRe: Please post a commentmemberMike Melnikov5-Sep-01 4:24 

Thanks, Christian, for your kind words.
 
I am opened for questions.
 
Mike
 

GeneralRe: Please post a commentmemberAnonymous14-Sep-01 5:05 
I like templates,
but your classes are a bit strange and I don't understand it that much.
But they seem powerful. I'll try to use them.
And maybe a working sample with source code would allow the developpers to understand it very quickly !
 
Also, you could correct all the "than" with "then" (the "bad" english)
 

 
Suspicious | :suss:
GeneralRe: Please post a commentmemberAnonymous14-Sep-01 5:06 
oups sorry there is one !
I check it.

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

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