Yes I agree that this is quite confusing. From memory there are cases where the PCDATA/CDATA isn't at child which is why I added xml_node::child_value(), xml_node::find_child() etc. This also explains why the PCDATA/CDATA can't be the nodes value.
It is possible that refactoring the code could improve areas like this, but I've just learnt to live with it.
Perhaps this has been talked a lot but I can not stop my self from writing this.
One of the reasons of XML is connecting platforms, apps through text encoded messages, to achieve this you need compliance. Implementing a fully (95%-98%) compliant XML parser is really hard. Usually an average Dev can get to 80% pretty quickly and the experienced can get to %90. The rest is all egde cases and getting them right requires extensive testing suites to ensure compat between different platforms. I know this by experience. There are quite a few xml parser implementations out there. Users are usually best served when the xml parser implementations are recognized by the W3C Recommendations. Other implementations can not go any further than academic studies as the cost of them making interop with the rest of the world sky rockets as dev's are trying to achieve %95 compat.
On a new xml_node object, setting the value to "" caused an access violation.
Changed the following lines of strcopyinsitu: size_t l = (*dest) ? _tcslen(*dest) : 0; //How long is destination?
if(l >= _tcslen(src)) //Destination is large enough, so just copy.
return TRUE; //Success.
To read: size_t l = (*dest) ? _tcslen(*dest) : 0; //How long is destination?
if(l >= _tcslen(src) && l > 0) //Destination is large enough, so just copy.
return TRUE; //Success.
We just stepped into the same issue. Our fix was slightly different. Instead of:
if (l >= _tcslen(src) && l > 0)
if (l >= _tcslen(src) && *dest)
I think both solutions may work. Basically, you want to protect from writing into a NULL pointer and get into the 'else' part of the 'if' statement.
BTW, we converted this thing to compile using gcc under Linux (embedded BusyBox for XScale/ARM). It took a little doing but it seems to work fine. Most of the changes were Unicode (_T, _tcs...) related and one problem with a method's abiguity. If anybody needs this, sent me a note.
I downloaded the code and attempted to compile it (VC6, Oct2001SDK). I get this kind of compile error:
c:\projects\pug\pugxml.h(1816) : error C2977: '_Ranit' : too many template arguments
c:\program files\microsoft visual studio\vc98\include\utility(77) : see declaration of '_Ranit'
c:\projects\pug\pugxml.h(1844) : see reference to class template instantiation 'pug::xml_iterator<_Ty,_Diff,_Pointer,_Reference>' being compiled
Also, the article makes mention of CPugXmlBranch and lots of wonderful methods to use. However, I can't find this class or anything even with with word 'branch' in it.
#if _MSC_VER < 1300
class xml_iterator : public std::_Ranit<_Ty,_D>
class xml_iterator : public std::_Ranit<_Ty,_Diff,_Pointer,_Reference>
class xml_iterator : public std::random_access_iterator_tag
Int the pugxml.h, the class name are "STL like" named. I think you find what you need in xml_node class.
Now that I read the pugxml.xml file that was supplied, I see that Kristen noted that the MS way of naming (Hungarian notation, CamelCase) was abandoned. That's fine by me as I would also like to use this eventually in an embedded Linux app.
First I would like to thank you for this parser, it really saved me a lot of time. however, when I tried to compile it with Unicode support (wchar_t) i run into some problems. so I have made the following changes, and I will be happy to send them to you if you whish. the changes are: 1. Replaced std:string with basic_string<TCHAR> 2. in load_file the buffer is tested for Unicode text and if it is not text is converted to Unicode - this makes it windows dependent since isTextUnicode is used.
I can get tag_a 's value("the data") in xml segment1, bug I can't get it in xml segment2. Sorry for my English. Thanks!