Sign in to follow this  

tiny XML problem

This topic is 4594 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


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

This topic is 4594 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this