   Grabbing, Converting + Storing XML Data
  My plan of action is to use TinyXML to grab a load of game settings from GameSettings.xml:<?xml version="1.0" encoding="utf-8"?><settings>  <gamename type="string">Le Physics Sandbox</gamename>  <developer type="string">Alexander Brook Perry</developer>  <version type="float">0.1</version>  <screenwidth type="int">800</screenwidth>  <screenheight type="int">600</screenheight>  <fullscreen type="bool">1</fullscreen></settings>Grabbing the data with TinyXML I'm working on now and shouldn't have any problems.The thing I'm worried about though is once I have the data, how can I store it?I have the boost library so a good choice would be boost::map, with the first being a string identifier but then what do I set the second to?Each values from the XML file can be either string, float, int or bool but I don't know how I can store all of these in the same list.I'm trying to sort this so that I can do something along the lines of settings["gamename"] or settings["version"]. Thanks.Thanks, Alex[Edited by - alexgeek on April 26, 2009 4:07:12 PM]
  boost::variant   ;  I don't see how that would help, all that means is that I can store two different types of data boost::variant<t1, t2>Whereas I want to be able to store <std::string, float OR int OR std::string>   ;  I think I'll do something like the followingstore the values instd::map<std::string, boost::variant<int, std::string>> which would correspond to:<elementname, <type, value>>I'd then define the types:#define X_STRING  0#define X_FLOAT   1#define X_INT2#define X_BOOL    3then set up some macros or functions to convert when I grab them.I'll let you know what I come up with.   ;  If you're going to strongly type your settings in XML, you might as well just strongly type them in code as well and avoid any fancy systems that are prone to user error.  Something like this works well enough:<?xml version="1.0" encoding="utf-8"?><settings>  <gamename>Le Physics Sandbox</gamename>  <developer>Alexander Brook Perry</developer>  <version>0.1</version>  <screenwidth>800</screenwidth>  <screenheight>600</screenheight>  <fullscreen>1</fullscreen></settings>class GameSettings{public:   void Load_From_XML(const std::string& filename);   const std::string& Get_Gamename() const { return Gamename; }   const std::string& Get_Developer() const { return Developer; }   float Get_Version() const { return Version; }   int Get_Screen_Width() const { return ScreenWidth; }   int Get_Screen_Height() const { return ScreenHeight; }   bool Get_Fullscreen() const { return Fullscreen; }private:   std::string Gamename;   std::string Developer;   float Version;   int ScreenWidth;   int ScreenHeight;   bool Fullscreen;};;  I'm almost there with this way, I may aswell carry on and add some error checking when I've got the time.One big problem I have is when i try to grab the type attribute:type = elmnt->QueryIntAttribute("type", type);I get a whole mess of errors that tell me nothing:Error1error LNK2019: unresolved external symbol "public: char const * __thiscall TiXmlElement::Attribute(char const *)const " (?Attribute@TiXmlElement@@QBEPBDPBD@Z) referenced in function "public: __thiscall GameSettings::GameSettings(void)" (??0GameSettings@@QAE@XZ)Appmain.objPhysics SandboxError2error LNK2019: unresolved external symbol "public: char const * __thiscall TiXmlElement::GetText(void)const " (?GetText@TiXmlElement@@QBEPBDXZ) referenced in function "public: __thiscall GameSettings::GameSettings(void)" (??0GameSettings@@QAE@XZ)Appmain.objPhysics SandboxI don't see the problem, I'm doing it just like the tutorial says:   xml = NULL; xml = new XMLParser(SETTINGSFILE); // encapsulates tinyxmlTiXmlHandle root = xml->GetRootHandle(); // just gives a handle to <settings>TiXmlElement* elmnt = root.FirstChildElement().Element();for(elmnt; elmnt; elmnt = elmnt->NextSiblingElement() ){std::string name, value; int type = 0;value = std::string(elmnt->GetText());type = elmnt->QueryIntAttribute("type", type);name = std::string(elmnt->Value());} [Edited by - alexgeek on April 26, 2009 6:32:47 PM];  You need to include the TinyXML source files in your project so that get compiled and linked with your code.  Offhand I know there's TinyXml.cpp, plus a few others.   ;Quote:Original post by ZipsterIf you're going to strongly type your settings in XML, you might as well just strongly type them in code as well and avoid any fancy systems that are prone to user error.Or you could use a markup language that already defines types (JSON, or Python expression syntax). Of course, there is no such thing as "not prone to user error" :) One of your users will try to specify a screen width of "hi mom" sooner or later, no matter how you've decided the program will handle that case.   ;  I prefer XML, JSON is quite ugly and less common.The tinyxml includes are included (#include "tinyxml.h") and they are working, if I comment out that line the rest of it works.There just seems to be a problem with grabbing that attribute.   ;Quote:Original post by ZahlmanOr you could use a markup language that already defines types (JSON, or Python expression syntax).  Of course, there is no such thing as "not prone to user error" :) One of your users will try to specify a screen width of "hi mom" sooner or later, no matter how you've decided the program will handle that case.Except I'm saying that dealing with types in data at all is the exact opposite of what the OP should be doing in this case.  There is some piece of code somewhere that needs to know the width of the screen, and expects that value to be an integer.  There is another piece of code that needs to know whether or not the application starts in fullscreen, and expects that value to be a boolean.  The code already knows what data it needs and how it wants it (the type); the XML only exists to literally fill in the values.  Adding a mechanism that allows you to define or change types at that point is wasted effort, since the code isn't going to suddenly expect new or different types because the data changed.  Except something like this:int screenWidth = Settings.Get<int>("screenwidth");Is most certainly more prone to programmer error than this:int screenWidth = Settings.Get_Screen_Width();Since it requires the programmer to remember the type and name at every point the data is needed.  You could argue that this might improve things a little:typedef int ScreenWidthType;const char* ScreenWidthName = "screenwidth";int screenWidth = Settings.Get<ScreenWidthType>(ScreenWidthName);But at that point, why do you support such a system in the first place if everything on the right side uses nothing but types and values known at compile-time?If the OP were using some form of scripting or otherwise data-driving the behavior of the code itself, that would be one thing and might necessitate the need to define and change types in data.  But I haven't seen any evidence of this yet, and when all you're doing is filling in values in XML, such a system is unnecessary and only adds room for error.Data error itself it a separate issue, since no matter where the type information comes from, if the data is the wrong type (such as a "hi mom" where an integer conversion is going to be performed), then a separate mechanism is required to handle those cases.   