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

Read and Write application parameters in XML

By , 30 Jun 2003
 

Sample Image - maximum width is 600 pixels

Introduction

This article provides an easy way to load and save the parameters of an application in XML format.

XML is a convenient format to deal with the parameters of applications for the following reasons:

  • It's text, so you can easily check the values and modify them with a classical editor (by the way, IE 5.0 shows XML in a very nice way).
  • It's based on a tree so you can have your parameters saved in a structured way.
  • It's platform and language independent.
My goal was not to parse an XML file, but to give an easy way to read and write the data. So the code is based on A simple STL based XML parser by David Hubbard. I would really like to thank him for his parser, it's a very good work! Moreover it saved me a lot of time, even if I made a few modifications in his original code to fulfill my goals.

The code is entirely based on STL. It compiles on linux, too. I guess it will compile on any other platform/compiler that supports STL.

Using the code

Now let's take an example to explain more precisely what you can do with ParamIO. Let's assume you have an application to show some text on the screen in a given color and in a given font (the demo project). The parameters of your application will be the text (1 string), the color (3 values RGB) and the font (1 string for the font name and 1 double for the font size). You want to be able to save those parameters on the disk and load them for a later use. A nice XML file containing those values can look like this:

<PARAMS>
  <TEXT>Hello world</TEXT>
  <COLOR>
	<RED>50</RED>
	<GREEN>128</GREEN>
	<BLUE>255</BLUE>
  </COLOR>
  <FONT>
	<NAME>Arial</NAME>
	<SIZE>12.0</SIZE>
  </FONT>
</PARAMS>
Let's say we have the following variables in the application :
std::string _text;                 // The text
int _red, _green, _blue;           // color
std::string _fontName;             // font name
double _fontSize;                  // font size
The code to write the previous file will be :
ParamIO outXml;

outXml.write("PARAMS:TEXT", _text);

outXml.write("PARAMS:COLOR:RED",   _red);
outXml.write("PARAMS:COLOR:GREEN", _green);
outXml.write("PARAMS:COLOR:BLUE",  _blue);

outXml.write("PARAMS:FONT:NAME", _fontName);
outXml.write("PARAMS:FONT:SIZE", _fontSize);

outXml.writeFile("filename.xml"); // Finally write the file to disk
As you can see, it's very easy. In the write method, the first parameter is a char* that defines the position in the XML tree. This is similar to XPath, but I didn't know XPath at the time I wrote this code, I would have used the '/' instead if I had known. The second parameter gives the value you want to write. write is a templated method so you can write almost any kind of variable, from int to std::string. Reading the file is also straightforward :
ParamIO inXml;

inXml.readFile("filename.xml"); // Read the file from disk

inXml.read("PARAMS:TEXT", _text, std::string("Hello world"));

inXml.read("PARAMS:COLOR:RED",   _red,   0);
inXml.read("PARAMS:COLOR:GREEN", _green, 0);
inXml.read("PARAMS:COLOR:BLUE",  _blue,  0);

inXml.read("PARAMS:FONT:NAME", _fontName, std::string("Arial"));
inXml.read("PARAMS:FONT:SIZE", _fontSize, 12.0);
You may be surprised by the third parameter of the read method. What does it mean? It's the default value of the parameter you try to read. Imagine you want to read a file like the previous one and the size of the font is not specified, then _fontSize will be automatically set to its default value 12.0. It's a very useful behaviour when you have several versions of a same application and some versions have parameters that didn't exist in older ones. It ensures that you still can read the old files, filling the missing values with default ones. It also lets you load a file that doesn't exist and set all the parameters with their default values.

ParamIO lets you read and write XML coming from streams also, it should be useful if you want some applications to exchange data through sockets for example.

The demo application includes a XML dialog box. With this dialog box (CXML_Dialog), you can visualise and modify any XML tree. I used it a lot, it's working really well. In case your parameter name contains FILENAME inside (e.g FONT_FILENAME), you'll see a button appear, and if you click on it, you'll obtain an open file dialog where you can find your file. I used this CXML_Dialog dialog box a lot and I'm very happy about it, it works really fine. CXML_Dialog uses a class from Easy Navigation Through an Editable List View by Lee Nowotny. I really thank him for the job, it works perfectly.

If you have any comments, suggestions or improvements let me know.

History

20 Nov 2002 : first version with GUI demo, with comparison capabilities

20 June 2003:

  • modified the website, added src download without the GUI demo
  • Added support for MFC CString has been added thanks to Paul Kissel : to enable CString read/write, just define _PARAMIO_CSTRING_SUPPORT_ in the compilation options.
  • Added a method to erase a node or an entire subtree as been added, thanks to Ogi's suggestion.

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

Arnaud Brejeon
Web Developer
China China
Member
I've been living & working in Tokyo since 2000 . I'm currently working in Gentech Corp. (www.gen.co.jp), developing computer vision applications, especially in the field of face detection.
 
I've been interested in C++ for quite a while and recently discovered Ruby.
 
My hobbies are trekking, japanese food, yoga & onsens.

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   
QuestionErrors in VS2005memberMember 83284985 Jan '12 - 23:33 
I am also getting lot of errors in vs2005.
Can somebody mail me the code which can compile succesfully in vS2005.
 
Thanks
Mayank
QuestionVS2010 compilation errormemberTheSpad31 Aug '11 - 23:50 
We had problems with VisualStudio 2008 compilation, which we solved by defining #define _HAS_ITERATOR_DEBUGGING 0 and #define _SECURE_SCL 0.
With VS2010, although with these definitions, we have the compilation error C2440: 'static_cast': cannot convert from 'XML_Node *' to 'XML_Node: nodes_iterator'
Someone can help us?
 
Francesco
AnswerRe: VS2010 compilation errormemberSebastian Michalski6 Aug '12 - 23:43 
Same problem :(
Generalgood codememberDonsw8 May '09 - 16:17 
Very nice work, thought about redoing it in c#?
 
cheers,
Donsw
My Recent Article : Ajax Calendar Control

GeneralUpdate to XML ParamIO for Visual Studio 2008memberRudolf Cardinal24 Apr '09 - 3:48 
The XML ParamIO class of 2002-3, whilst very nice, breaks on Visual Studio 2008, because it relies on an assumption that STL iterators are implemented as pointers. That was true in Visual C++ 6 (though it wasn't guaranteed to be true); it's no longer true in VS2008.
 
If you're starting a project from scratch, you might want to look at the Boost Serialization library (www.boost.org).
 
However, if you need to get this class working for back-compatibility, I've published an updated version (XMLParamIO2) at http://pobox.com/~rudolf/code[^] .
 
This works fine on VS2008 (at least, the ParamIO::readFile, ParamIO::read, ParamIO::write, and ParamIO::writeFile functions work, which is all I was using) and is back-compatible with the old file structures.
 
Details of the significant changes are in ParamIO.h.
 
The class now also supports the MFC CString class by default (though there's a #define that you can remove if you want to get rid of this support).
GeneralAttribute Read/Write Needed....memberJasonAw23 Mar '09 - 16:22 
It's the best XML read/write program I found so far, thanks to Arnaud...but if Arnaud or anyone else is kind enough to add an additional feature to read/write element with attribute then it will become perfect! Can anyone please help? Smile | :)
Generalsome clarificationmembervinodkumar subramaney31 Jan '09 - 5:59 
hi,
This peace of code is really great.But i could'nt understand some area.Could some one help me out.
 
I was going through the code (XMLParser) and had some doubt..... could some one plz explain me this part of the code...
 

bool XmlParser::hasNullTag ()
{
// get end of first tag
char * buffer = _buffer + _firstTagEnd - 1;
 
// if null tag marker
if ( *buffer == '/' && *(buffer+1) == '>' )
return true;
else
return false;
}
 
actually, we close a tag like this right??
 
<color></color>
 
how does he find whether its empty tag or not???? I'm confused!!!
 

thanks & regards,
Vinod.
Generalthank u da mandayamemberprithivintpl22 May '08 - 1:41 
Thakk for ur code sir
Generalthank you for your codemembertjroamer12 May '08 - 6:08 
this is really a great work. Using your code I finished my master thesis. Now in my professional field, I have been still using your code. It has been working so well!
Great! Thank you. Poke tongue | ;-P
Question as first line in the filememberArmandopoulos26 Apr '08 - 10:04 
Hello,
 
I would like to put this line () as first line in all xml file that i´m writing with this Code or library.
 
Is it possible to do that? if yes can anybody tell how can i do that ?
 
Thank in advance.
 
Regards.
 
Armando

Questionapplication parametermembernithin kumar4 Dec '07 - 19:11 
I download the demo project and source code.
I can't understand how to run the application parameter.
can anyone explain it???
 
Thanks,
Nithin
QuestionHi anyone got this working on VS2005?membermagiceyes11823 Jul '07 - 17:46 
I get so many errors compiling, if anyone can send me an updated version that works to lodoss118@gmail.com thanks.
GeneralAttributes againmembersamcct31 Oct '06 - 6:24 
Hi,
 
Can anyone give me some helps to write XML node with attribute?
 
For example:
 
?
 
Thanks,
Samo
 

QuestionParamIO and VisualStudio2005membermexicanchili19 Sep '06 - 2:11 
Hi,
 
I don't know if anybody still cares about ParamIO. I'm about to convert all our projects to VisualStudio2005.D'Oh! | :doh:
ParamIO doesn't compile. I get tons of compiler errors like this:
 

xml_node.h(170) : error C2440: 'static_cast' : cannot convert from 'XML_Node *' to 'XML_Node::nodes_iterator'
No constructor could take the source type, or constructor overload resolution was ambiguous

 
Unluckily the programmer who wrote this particular project has left the company. I'm wondering if anybody probably has converted ParamIO successfully to VS2005 and could share his sources with me thus saving me a lot of work.
 
Thanks a lot
Rita
AnswerRe: ParamIO and VisualStudio2005membergyarmit8 Jan '07 - 4:07 
Hi Rita,
Did you manage to port to new VS?
Please, let me know. I am interested in it.
Thank you very much,
Greg
GeneralNode searching errormemberGintas28 Oct '05 - 8:36 
Hi,
Thanks for the code. I have found that error by accident. Sample of testing code below:
ParamIO outXml;
outXml.write("VIEWER:PARAM1", "abc");
outXml.write("VIEW:PARAM2", 1); // By accident typed VIEW instead of VIEWER
outXml.writeFile("filename.xml"); // Finally write the file to disk
 
The result will be:
<VIEW>
< PARAM1>abc</PARAM1>
< PARAM2>1</PARAM2>
</VIEW>
 
Second "write" call finds VIEWER node instead of VIEW node. After that it changes node name from VIEWER to VIEW and adds new parameter.
Best regards,
Gintas
Generalstatic_cast errormemberApex Watson22 Aug '05 - 10:25 
I am getting the following error on first compile of the test project:
 
'static cast' : cannot convert from 'const XML_Node *' to 'XML_Node::nodes_const_iterator'
 
on the following two lines:
 
// First we need to find the final node
XML_Node::nodes_const_iterator res, end, begin;

begin = static_cast<XML_Node::nodes_const_iterator>(&_node);
end = static_cast<XML_Node::nodes_const_iterator>(&(_node) + 1);

 
It appears that _node is a private variable of type XML_Node in the XML_Param_Notify class. XML_Node::nodes_const_iterator is just a typedef defined as:
 
typedef std::vector<XML_Node>::const_iterator nodes_const_iterator;
 
So it looks like this code is trying to cast the address of _node into an iterator of type nodes_const_iterator. An iterator is just a pointer to an address right? It seems like this should be doable, and I'm guessing that since no one else has posted this problem yet it has something to do with what I'm doing on my end. Any ideas?
 

 

GeneralRe: static_cast errorsussAnonymous31 Aug '05 - 12:46 
This was discussed in prior posting.   VS.NET vs. VC++ 6.0.   Change line 218 in VS.Net to:
 
XML_Node::nodes_const_iterator res;
XML_Node::nodes_const_iterator begin((std::vector<XML_Node>::_Tptr) &_node);
XML_Node::nodes_const_iterator end((std::vector<XML_Node>::_Tptr)(&(_node) + 1));

GeneralW3C compliancememberUmut Alev25 Jul '05 - 21:03 
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.
GeneralReading with two or more same elementsmembersdarisi26 Apr '05 - 23:12 
I'm having problems reading an xml file that looks like this,
 
<PARAMS>
   <TEXT>Hello world</TEXT>
   <COLOR>
     <RED>50</RED>
     <GREEN>128</GREEN>
     <BLUE>255</BLUE>
   </COLOR>
   <COLOR>
     <RED>60</RED>
     <GREEN>188</GREEN>
     <BLUE>252</BLUE>
   </COLOR>
</PARAMS>
 
That is, if I have two or more color nodes, how would I read it using this program? It reads only the first one. Is it possible to read such kind of files using this application???
 
TIA
 
http://www.TechiesAbode.com/

GeneralFor Dev-C++4.9.9.2/gcc 3.4.2memberV.Kotov16 Mar '05 - 23:55 
In XML_Node.h I had to add:
#include <sstream>
GeneralRe: For Dev-C++4.9.9.2/gcc 3.4.2memberDenis Chekhlov16 May '05 - 6:54 
Cheers.
 
I upgraded to a new kernel, and got the
message when trying to recompile my code
 
gcc version 3.4.3 20041212 (Red Hat 3.4.3-9.EL4).
 
It solved the problem.
GeneralWhite Spacessussbdm14 Mar '05 - 7:11 
I am having trouble with reading in white spaces with this code. I can write strings that contain white spaces, but when I try to read them in, it only returns the first word. I'm assuming I'm not the only one out there with this problem, anyone have a fix?
 
Thanks!
GeneralUpdatememberbobbymihalca8 Feb '05 - 22:32 
Long time ago i made some big modification to ParamIO to support success of reading, Path and multiple nodes.
Something like this can be used:
if(!Cfg.read("/MyApp/Layout/Layer[2]/Type", type,""))
{

}
This also should work with write.
Maybe Arnud will put my code here in a separate archive.
 
Arnud please let me know if you are wiling to upload my code.

GeneralRe: UpdatememberArnaud Brejeon10 Feb '05 - 7:46 
For sure! I'd be glad to upload your code, if you send it to me.

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

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130523.1 | Last Updated 1 Jul 2003
Article Copyright 2001 by Arnaud Brejeon
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid