Problem with tinyXML reading attributes

Started by
5 comments, last by wezyap 15 years, 11 months ago
Hi all. I have a problem with tinyXML, I have used tinyXML many times before, but this is the first time I have encountered this problem. the problem is a runtime error. This is a snippet of the code

//****************get animation data************

	//go to library_animation
	TiXmlElement *elmLibrary_animation=0;
	elmLibrary_animation=RootNode->FirstChildElement("library_animations");

	//spinn through the library_animations to get each animaton element
	int numberofanimationelm=0;
	TiXmlNode* node = 0;
	TiXmlElement* todoElement = 0;
	node = elmLibrary_animation;
	todoElement = node->ToElement();

	for( node = todoElement->FirstChild( "animation" ); node; node = node->NextSibling( "animation" ) )
	{
		TiXmlElement* tmpElm;
		tmpElm=node->ToElement();

	
    	SceneGraphAnimations[numberofanimationelm].id=tmpElm->Attribute("id");
		
		//for each animation, spinn throgh sources
		int numberofsources=0;
		TiXmlNode* sourcenode=0;
		TiXmlElement* todoSourceElement=0;
		sourcenode=tmpElm;
		todoSourceElement=sourcenode->ToElement();
the program breaks at the line

SceneGraphAnimations[numberofanimationelm].id=tmpElm->Attribute("id");
SceneGraphAnimations is defined as

animation *SceneGraphAnimations;
"animation" is

typedef struct  
{
	const char* id;
	int numberofsources;
	int numberofsamples;
	int numberofchannels;
	anim_source *sources;
	anim_sampler *samples;
	anim_channels *channels;

	int numberof_Sources;
	int numberof_Samples;
	int numberof_Channels;
}animation;
If I comment out the line SceneGraphAnimations[numberofanimationelm].id=tmpElm->Attribute("id"); the app breaks at other places in the code like this one

//for each animation, spinn throgh sources
		int numberofsources=0;
		TiXmlNode* sourcenode=0;
		TiXmlElement* todoSourceElement=0;
		sourcenode=tmpElm;
		todoSourceElement=sourcenode->ToElement();

		for (sourcenode=todoSourceElement->FirstChild("source");sourcenode;sourcenode=sourcenode->NextSibling("source"))
		{
			TiXmlElement* tmpSourceElm=0;
			tmpSourceElm=sourcenode->ToElement();
			SceneGraphAnimations[numberofanimationelm].sources[numberofsources].id=tmpSourceElm->Attribute("id");

Here is a snippet from the XML file (it is a Collada dae file).

 <library_animations>
  
    <animation id="camera1.translate">
      
      <source id="camera1.translate_camera1_translate.X-input">
      
        <float_array id="camera1.translate_camera1_translate.X-input-array" count="14">.......</float_array>   
        <technique_common>
          <accessor source="#camera1.translate_camera1_translate.X-input-array" count="14" stride="1">
            <param name="TIME" type="float"/>
          </accessor>
        </technique_common>
        <technique profile="MAYA">
          <pre_infinity>CONSTANT</pre_infinity>
          <post_infinity>CONSTANT</post_infinity>
        </technique>
        
      </source>
output338.jpg.xs.jpg I would really appriciate any help, tips or tricks.
Advertisement
From what you've posted, it doesn't look like you'll break from this loop (unless you break inside).

for (sourcenode=todoSourceElement->FirstChild("source");sourcenode;sourcenode=sourcenode->NextSibling("source"))


I'm guessing the runtime error is do to memory allocation. Maybe you should try using a std::string instead.
Quote:Original post by Peter5897
From what you've posted, it doesn't look like you'll break from this loop (unless you break inside).

*** Source Snippet Removed ***

I'm guessing the runtime error is do to memory allocation. Maybe you should try using a std::string instead.


It breaks inside, at this line:
SceneGraphAnimations[numberofanimationelm].sources[numberofsources].id=tmpSourceElm->Attribute("id");


I tried this:
typedef struct  {	string id;	int numberofsources;	int numberofsamples;	int numberofchannels;	anim_source *sources;	anim_sampler *samples;	anim_channels *channels;	int numberof_Sources;	int numberof_Samples;	int numberof_Channels;}animation;


now it breaks at line 2180 in the xstring header file.
_Elem *__CLR_OR_THIS_CALL _Myptr()		{	// determine current pointer to buffer for mutable string		return (_BUF_SIZE <= _Myres ? _Bx._Ptr : _Bx._Buf);		}
I don't immediately see something that will give you the run-time error. However, I do have some recommendations that may help solve the problem.

1). Check out the TinyXML docs and tutorial. You need to do more error checking (throw in some asserts, or use Handles so you can better pinpoint where and why the error is occurring. Also I'm not sure why you find the need to do all of the Node to Element conversions. I think if you stick with some of the parsing conventions shown in the documentation, you will get more concise and bug-free code.

2). You could also use the STL string class instead of dealing with C-style pointers. Just define TIXML_USE_STL. In general, this is a C++ program, and you are using some C-style conventions.

3). As a sanity check, make sure SceneGraphAnimations[numberofanimationelm] is a valid element of the array when you access it.
Quote:Original post by Doggan
I don't immediately see something that will give you the run-time error. However, I do have some recommendations that may help solve the problem.

1). Check out the TinyXML docs and tutorial. You need to do more error checking (throw in some asserts, or use Handles so you can better pinpoint where and why the error is occurring. Also I'm not sure why you find the need to do all of the Node to Element conversions. I think if you stick with some of the parsing conventions shown in the documentation, you will get more concise and bug-free code.

2). You could also use the STL string class instead of dealing with C-style pointers. Just define TIXML_USE_STL. In general, this is a C++ program, and you are using some C-style conventions.

3). As a sanity check, make sure SceneGraphAnimations[numberofanimationelm] is a valid element of the array when you access it.


thanks for the tips =)
But this didn't fix the bug.

I tried this, just to see what tmpElm->Attribute("id"); contained:

TiXmlElement* tmpElm;		tmpElm=node->ToElement();		string test=tmpElm->Attribute("id");		printf("%s\n",test);		system("PAUSE");    	SceneGraphAnimations[numberofanimationelm].id=tmpElm->Attribute("id");


and got this as output
(null)Press any key to continue . . .
I think what is going on is that an "id" does not exist. Are you checking for null returns from your call to Attribute()? For example:

std::string test;if( tmpElm->Attribute("id") != NULL ){ test = tmpElm->Attribute("id");}


I've worked with TinyXML only once and I remember having a problem with case sensitivity. Are you sure your "id" is not "ID" or some other form?
Quote:Original post by Peter5897
I think what is going on is that an "id" does not exist. Are you checking for null returns from your call to Attribute()? For example:

*** Source Snippet Removed ***

I've worked with TinyXML only once and I remember having a problem with case sensitivity. Are you sure your "id" is not "ID" or some other form?


 <animation id="camera1.translate">


so there is no case sensitivity, problem. but you are right, it looks like tinyxml dosn't find the id attribute. wich is a bit weird since it finds the animation node, and loops through the child elements if I comment out the stuff that reads the attributes.

This topic is closed to new replies.

Advertisement