Jump to content
  • Advertisement
Sign in to follow this  
garyfletcher

tiny XML problem

This topic is 4844 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi there I'm trying to use tiny XML to develop a method of using a config file to describe some of the objects in a game. I have a profile.xml but I'm a littel confused as how to use the Tiny XML interface. I was hoping that someone might be able to point me in the right direction. profile.xml:
<?xml version="1.0" standalone=np>
<!-- Test profile -->
<SiSEProfile name="Circles">
   <OBJType type="GameObject">
   	<Name text="BallKey"></Name>
   	<Desc text="Bitmap for a 2D ball"</Desc>
   	<Attr>
   	   <DataFile text="File location for bitmap" value="./ball.bmp"</DataFile>
   	   <Coords>
   	      <xPos text="Initial X Coord" value="10"/>
   	      <yPos text="Initial Y Coord" value="10"/>
   	   </Coords>
   	</Attr>
   </OBJType>
</SiSEProfile>

Profile class header - SiSEProfile.h:
#ifndef INCLUDE_PROFILE_H
#define INCLUDE_PROFILE_H

#include <string>
#include <vector>
#include <map>
#include "tinyxml.h"

typedef struct
{
    std::string attType;
    std::string attDesc;
    std::string attValue;
} Attribute;

typedef struct
{
    std::string type;
    std::string name;
    std::string desc;
    std::vector <Attribute *> attributes;
} ProfileData;

class SiSEProfile
{
    public:
       SiSEProfile();
       SiSEProfile(std::string& fName);
       ~SiSEProfile();
       std::vector<std::string>& m_loadProfile(void);
       
    private:
        typedef std::pair<std::string, ProfileData*> profilePair;
        typedef std::map <std::string, ProfileData*> profileMap;
        profilePair mapPair;
        profileMap profile;
        std::string fileName;
        ProfileData* m_profile;
        Attribute* m_attribute;
        std::vector<std::string> m_keys;
        std::string m_key;
        void m_parseProfile(TiXmlDocument& profileDoc);
        void m_displayProfile(void);
        
    public:
        ProfileData*  m_getProfileData(std::string profileKey);
};

#endif

Profile class source - profile.cpp:
#include <cstdlib>
#include <iostream>
#include "SiSEProfile.h"
#include "SiSEException.h"

SiSEProfile::SiSEProfile()
{
    fileName = "profile.xml";
}

SiSEProfile::SiSEProfile(std::string& fName)
{
    fileName = fName;
}

SiSEProfile::~SiSEProfile()
{
    profileMap::iterator mapIter = profile.begin();
    profileMap::const_iterator mapEnd = profile.end();
    
    while(mapIter != mapEnd)
    {
        std::vector<Attribute *>::iterator attrIter = mapIter->second->attributes.begin();
        std::vector<Attribute *>::iterator attrIterEnd = mapIter->second->attributes.end();
        
        while(attrIter != attrIterEnd)
        {
            delete *attrIter;
            *attrIter = 0;
            
            ++attrIter;   
        }
        
        delete mapIter->second;
        mapIter->second = 0;
        
        ++mapIter;
    }
}

std::vector<std::string>& SiSEProfile::m_loadProfile()
{
    TiXmlDocument profileDoc(fileName.c_str());
    
    std::cerr << "XML document " + fileName << " : " << fileName.c_str() << std::endl;
    
    if(profileDoc.LoadFile())
    {
        throw SiSEException("Unable to open profile XML document");
    }
        
    m_parseProfile(profileDoc);
    
    m_displayProfile();
		
    return m_keys;  
}

void SiSEProfile::m_parseProfile(TiXmlDocument& profileDoc)
{
    TiXmlElement* profileName = 0;
    profileName = profileDoc.FirstChildElement("SiSEProfile");
   
    while (profileName)
    {
        const char* name = profileName->Attribute("name");
        m_profile = new ProfileData;
        
        if (name)
        {        
            TiXmlElement *objectType = 0;
            objectType = profileName->FirstChildElement("OBJType");
            
            while (objectType)
            {
                const char* objType = objectType->Attribute("type");
                
                m_profile->type = objType;
                
                TiXmlElement *objectName = 0;
                TiXmlElement *objectDesc = 0;
                TiXmlElement *objectAttr = 0;
                
                objectName = objectType->FirstChildElement("Name");

                if (objectName)
                {
                    std::cerr << "Name Sibling found" << std::endl;
                    
                    const char* text = objectName->Attribute("text");
                    
                    if(text)
                    {
                        std::cerr << "Name Sibling text found" << std::endl;
                        
                         m_profile->name = text;
                         m_key = m_profile->name;
                         m_keys.push_back(m_key);
                    }
                    else
                    {
                        throw SiSEException("Unable to find key for profile");   
                    }
                }
                    
                objectDesc = objectType->NextSiblingElement("Desc");
                
                if (objectDesc)
                {
                    std::cerr << "Desc Sibling found" << std::endl;
                    
                    const char* text = objectDesc->Attribute("text");
                    
                    if(text)
                    {
                        std::cerr << "Desc Sibling text found" << std::endl;
                        
                         m_profile->desc = text;   
                    }
                }
                
                objectAttr = objectType->NextSiblingElement("Attr");
                
                if (objectAttr)
                {
                    TiXmlElement* dataFile = 0;
                    TiXmlElement* coords = 0;
                    
                    while (objectAttr)
                    {    
                        dataFile = objectAttr->FirstChildElement("DataFile");
                        const char* text = objectAttr->Attribute("text");
                        const char* value = objectAttr->Attribute("value");
            
                        m_attribute = new Attribute;
                        
                        if(dataFile)
                        {
                            m_attribute->attType = "Datafile";
                            m_attribute->attDesc = text;
                            m_attribute->attValue = value;
                        }
                        
                        m_profile->attributes.push_back(m_attribute);
                        m_attribute = 0;
                        
                        coords = objectAttr->NextSiblingElement("Coords");
                        
                        if(coords)
                        {
                            m_attribute->attType = "Coords";
                            
                            TiXmlElement* xPos  = 0;
                            TiXmlElement* yPos  = 0;
                            
                            while(coords)   
                            {
                                xPos = coords->FirstChildElement("xPos");
                                
                                if(xPos)
                                {
                                    m_attribute->attDesc = text;
                                    m_attribute->attValue = value;
                                }
                                
                                m_profile->attributes.push_back(m_attribute);
                                
                                yPos = coords->NextSiblingElement("yPos");
                                
                                if(yPos)
                                {
                                    m_attribute->attDesc = text;
                                    m_attribute->attValue = value;
                                }
                                
                                m_profile->attributes.push_back(m_attribute);
                                m_attribute = 0;
                                
                                coords = coords->NextSiblingElement("Coords");
                            }
                        }
                        
                        objectAttr = objectAttr->NextSiblingElement("Attr");
                    }
                }

                profile.insert(profilePair(m_key,m_profile));

                objectType = objectType->NextSiblingElement("OBJType");
            }         
        }
        
        profileName = profileName->NextSiblingElement("SiSEProfile");
    }
    
    return;  
}

ProfileData* SiSEProfile::m_getProfileData(std::string profileKey)
{
    profileMap::iterator mapIter = profile.find(profileKey);
    
    if (mapIter != profile.end())
    {
        return mapIter->second;   
    }
    else
    {
        throw SiSEException("Unable to find profile");
    }
}

void SiSEProfile::m_displayProfile(void)
{
    profileMap::iterator mapIter = profile.begin();
    profileMap::const_iterator mapEnd = profile.end();
    
    while(mapIter != mapEnd)
    {
        std::cerr << "Type: " << mapIter->second->type << std::endl;
        std::cerr << "Name: " << mapIter->second->name << std::endl;
        std::cerr << "Desc: " << mapIter->second->desc << std::endl;
        
        std::vector<Attribute *>::iterator attrIter = mapIter->second->attributes.begin();
        std::vector<Attribute *>::iterator attrIterEnd = mapIter->second->attributes.end();
        
        while(attrIter != attrIterEnd)
        {
            std::cerr << "Attribute Type: " << (*attrIter)->attType << std::endl;
            std::cerr << "Attribute Desc: " << (*attrIter)->attDesc << std::endl;
            std::cerr << "Attribute Value: " << (*attrIter)->attValue << std::endl;
    
            ++attrIter;   
        }
        
        ++mapIter;
    }
    
    return;
}

The output I'm getting from the display function:
XML document profile.xml : profile.xml
Name Sibling found
Name Sibling text found
Type: GameObject
Name: BallKey
Desc: 
Profile key: BallKey
Terminating normally.

It looks like the 1st node is being read and parsed correctly but not the rest. Am I using the NextSiblingElement() function incorrectly. Is my XML file set out incorrectly. I'm very new to XML so I'm not sure what I'm doing wrong. Even some TinyXML tutorials would be helpful.

Share this post


Link to post
Share on other sites
Advertisement


I dont know if this matters or not, but you have something like this:
<somenode value='3' </somenode>
You never closed the node.
You can either do this:
<somenode value='3'> </somenode>
Or do this:
<somenode value='3'/> This slash means that it has nothing in between it like text or other nodes.


But, I may be wrong.

Share this post


Link to post
Share on other sites
You're trying to read directly from the TiXMLDocument. Try doing:


TiXmlElement *pRoot = Doc.Root();


And then reading from pRoot.

Toolmaker

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!