Sign in to follow this  
Mybowlcut

[C++] Objects reading XML

Recommended Posts

Hey. I'm currently trying to replace all the IO between my game and text files with IO between the game and XML files. Just wondering what the best way to read objects from XML files is... Should I make non-member friend functions in each object that can be loaded from an XML file? Or should I make a member function called Read or something that is a virtual function carried down from a XML_Readable abstract class? Is it also possible to somehow use operator>> and derive a class from std::istream for this? Or would it not work? Cheers.

Share this post


Link to post
Share on other sites
My solution was to go with the fact that Xml documents are trees.

So I just created a XMLNode class that was a descended from my TreeList object (link list tree, i.e, it has children as well as siblings). I then have some recursive search functions going depth and breadth. It works well enough.

My thought: XML should be expected to be well formed and matching your schema, if it isn't fail gracefully its the best way, and then lecture yiur user about garbage in garbage out :)

Share this post


Link to post
Share on other sites
I've used Xerces and TinyXML in C++.

Tiny is probably what you want. It's easy to use, and reasonably quick.

Xerces is best for when you want to use the whole 9 barreled rotating shotgun features of XML. Xpath queries are really convenient, but I never found it particularly snappy.

Share this post


Link to post
Share on other sites
Hey guys.

Sorry, I should have mentioned that I'm already using TinyXML(++).

I was actually wondering about the best way to read/write game objects using TinyXML. The TinyXML documentation says that there are overloaded insertion/extraction operators for some classes, so I was wondering if I should go with using >>/<< or make my own Read/Write functions.

Edit: Quotes won't take tabs or spaces so excuse the indentation, but as an example, I'd have an XML file for a Level that looks something like this (I don't know the proper format yet, but this is just an example):
Quote:
<?xml version="1.0" ?>
<level width="10" height="10">
<background_tiles>
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" /> <tile name="tile2.png" /> <tile name="tile2.png" />
<tile name="tile2.png" />
</background_tiles>
<object_tiles>
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="portal.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="tree_bottom.png" passability="2" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" /> <object_tile name="blank.png" passability="1" />
<object_tile name="blank.png" passability="1" />
</object_tiles>
<foreground_tiles>
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="tree_top.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" /> <tile name="blank.png" /> <tile name="blank.png" />
<tile name="blank.png" />
</foreground_tiles>
<portals>
<portal to_level="level2" from_x="1" from_y="1" to_x="4" to_y="4" />
</portals>
</level>


So far, I've got something like this going for writing it to an XML file (I haven't tested it yet):
void Level::Write_Tiles(ticpp::Element* root, const std::string& type, tile_vector& v)
{
using namespace ticpp;
Element* tile = NULL;
Element* tiles = new Element(type);
root->LinkEndChild(tiles);
for(tile_it it = v.begin(); it != v.end(); ++it)
{ // Write each background tile.
tile = new Element("tile");
tile->SetAttribute("name", it->File_Name());
tiles->LinkEndChild(tile);
}
}

void Level::Write_Object_Tiles(ticpp::Element* root)
{
using namespace ticpp;
Element* tile = NULL;
Element* object_tiles = new Element("object_tiles");
root->LinkEndChild(object_tiles);
for(object_tile_it it = this->object_tiles.begin();
it != this->object_tiles.end(); ++it)
{ // Write each background tile.
tile = new Element("object_tile");
tile->SetAttribute("name", it->File_Name());
tile->SetAttribute("passability", static_cast<int>(it->Passability()));
object_tiles->LinkEndChild(tile);
}
}

void Level::Write_Portals(ticpp::Element* root)
{
using namespace ticpp;
Element* portal = NULL;
Element* portals = new Element("portals");
root->LinkEndChild(portals);
for(portal_it it = this->portals.begin();
it != this->portals.end(); ++it)
{ // Write each background tile.
portal = new Element("portal");
portal->SetAttribute("to_level", it->To_Level());
portal->SetAttribute("from_x", it->From_Pos().y);
portal->SetAttribute("from_y", it->From_Pos().y);
portal->SetAttribute("to_x", it->To_Pos().x);
portal->SetAttribute("to_y", it->To_Pos().y);
portals->LinkEndChild(portal);
}
}

void Level::Write(const std::string& file_name)
{
using namespace ticpp;

Document document;
Element* tile = NULL;

Declaration* dec = new Declaration("1.0", "", "");
document.LinkEndChild(dec);

Element* root = new Element("level");
document.LinkEndChild(root);
root->SetAttribute("width", size.x);
root->SetAttribute("height", size.y);

Write_Tiles(root, "background_tiles", background_tiles);
Write_Object_Tiles(root);
Write_Tiles(root, "foreground_tiles", foreground_tiles);
Write_Portals(root);
}



[Edited by - Mybowlcut on November 22, 2008 5:42:07 AM]

Share this post


Link to post
Share on other sites

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