Sign in to follow this  
Eriond

Need some help with TinyXML

Recommended Posts

I have an xml-file which looks like this:
<ItemList>
	<Item>
		<Name>Spear</Name>
		<Description>This is an ordinary spear</Description>
		<Value>100</Value>
		<Magical>0</Magical>
	</Item>
	<Item>
		<Name>Mace</Name>
		<Description>This is an ordinary mace</Description>
		<Value>75</Value>
		<Magical>0</Magical>
	</Item>
</ItemList>
I'm trying to parse it using TinyXML into a ItemData struct.
struct ItemData
{
	std::string name;
	std::string description;
	int value;
	bool magical;
};
This is with TIXML_USE_STL defined. The problem is that I don't understand how to get the text from inside <Name></Name> for example. This code just prints 0000000
TiXmlDocument doc( "ItemList.xml" );
	TiXmlHandle handle( &doc );
	TiXmlText* s = handle.FirstChild( "ItemList" ).FirstChild( "Item" ).FirstChildElement( "Name" ).Text();
	std::cout << s << std::endl;
Another question too, how do I read each entry into a ItemData struct and store all of them in a vector?

Share this post


Link to post
Share on other sites
Are you sure that the xml file is being parsed correctly when you open it with TiXmlDocument doc( "ItemList.xml" ); ? If there is an error in the parse, then probably all your attempts to read anything out of the doc will fail.

Does specifying the filename like that even open and load the XML file? From the example that comes with TinyXML, it appears that it should be used like:

TiXmlDocument doc( "demotest.xml" );
bool loadOkay = doc.LoadFile();

Just specifying the filename in the ctor does not actually cause the file to be loaded and parsed.

Are you sure that your XML file is correctly formed, header tag an all? If you've checked all these things and its still failing, can you provide some more information?

Share this post


Link to post
Share on other sites
I had a similiar problem with TinXML and I don't think I ever figured it out... I just couldn't read items outside of tags (ie. <name>MyName</name>.

SO I just resorted to <name="MyName"></name>

I know, not a solution really, but it works 100% of the time ;)
If you find out what is wrong, please post so that I can go back to my code and fix it too :)

Share this post


Link to post
Share on other sites
It worked when I added doc.LoadFile(), thanks for that Scrime. Now on to the next problem :) My xml-file is exactly as in the first post. Now I want to read each Item-tag into a ItemData struct. I've managed to read the first item like this.
ItemData id;
TiXmlDocument doc( "ItemList.xml" );
if( !doc.LoadFile() ) return;
TiXmlHandle root( &doc );
TiXmlHandle handle = root.FirstChild( "ItemList" ).FirstChild( "Item" );
id.name = handle.FirstChildElement( "Name" ).FirstChild().Text()->Value();
id.description = handle.FirstChildElement( "Description" ).FirstChild().Text()->Value();
id.value = boost::lexical_cast< int >( handle.FirstChildElement( "Value" ).FirstChild().Text()->Value() );
id.magical = boost::lexical_cast< bool >( handle.FirstChildElement( "Magical" ).FirstChild().Text()->Value() );


The thing I don't understand is how to choose the next Item-tag for reading so I can read the file into a vector of ItemData. Any ideas would be nice :)

Share this post


Link to post
Share on other sites
Quote:
Original post by Eriond
I'm trying to parse it using TinyXML into a ItemData struct.

If I were bishop_pass, I'd tell you to use Lisp. Your data file would then be code automatically! You wouldn't have to "parse it into a struct" because it would already be a struct! Similarly, if you were using .NET, you could use it's conversion utility to create a C# class based on the XML schema. You'd then be able to serialize the class from the XML file in two lines of code!

Sorry, I know it's not much help, I just thought it'd be useful for you to be aware of this information, if you aren't already.

I need more coffee...

Share this post


Link to post
Share on other sites
Something roughly like this should work.

TiXmlElement* pElem;
for (pElem = root.FirstChildElement("ItemList").FirstChildElement("Item").Element();
pElem != NULL;
pElem = pElem->NextSiblingElement("Item"))
{
ItemData id;
TiXmlHandle handle(pElem);
id.name = handle.FirstChildElement( "Name" ).FirstChild().Text()->Value();
id.description = handle.FirstChildElement( "Description" ).FirstChild().Text()->Value();
id.value = boost::lexical_cast< int >( handle.FirstChildElement( "Value" ).FirstChild().Text()->Value() );
id.magical = boost::lexical_cast< bool >( handle.FirstChildElement( "Magical" ).FirstChild().Text()->Value() );
container.push_back(id);
}



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