irrXML parsing xml tree ?

Post your questions, suggestions and experiences regarding game design, integration of external libraries here. For irrEdit, irrXML and irrKlang, see the
ambiera forums
Post Reply
malimravbg
Posts: 3
Joined: Mon Sep 12, 2005 10:01 am

irrXML parsing xml tree ?

Post by malimravbg »

How to detect end of a node ?

<routes>
<route name="NAME1">
<waypoint name="POINT1"/>
<waypoint name="POINT2"/>
<waypoint name="POINT3"/>
</route>
<route name="NAME2">
<waypoint name="POINT4"/>
<waypoint name="POINT5"/>
</route>
</routes>

i.e. I can get all elements with :

Code: Select all

switch(xml->getNodeType())
{
	case irr::io::EXN_ELEMENT:
	if (routeNode.equals_ignore_case(xml->getNodeName()))
	{
		routeName = xml->getAttributeValue("name");
	} 
	else if (waypointNode.equals_ignore_case(xml->getNodeName()))
	{
		waypointName = xml->getAttributeValue("name");
	};
	break;
};	
but I can't detect how many childs a route node has.
irrXML reads nodes one by one as it goes through file. It has no posibility to detect parent and child node ? Am I right ?
How to detect how many childs parent node has ?

Some example would be great....
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

In your case you just add waypoint until a new route occurs. But this won't work with every XML structure, so there are probably other possibilities. I don't know irrXML that good.
Nalin
Posts: 194
Joined: Thu Mar 30, 2006 12:34 am
Location: Lacey, WA, USA
Contact:

Post by Nalin »

What I did was created a recursive function. The function load_node() would be called for each node. I then created a function that would check the lineage of the node. As you can see from my code, you can check what type of node you are calling. In your case, you would want to check for io::EXML_NODE::EXN_ELEMENT_END. Here is my code, in case it can help you further.

Code: Select all

s32 CRSettingBase::parse_node( io::IrrXMLReader *xml, xmlnode *parent, void *data )
{
	xmlnode node;

	if ( !xml->read() )
		return 1;

	if ( strlen(xml->getNodeName()) <= 0 )
		return 1;

	// John: These just screw everything up.  ;_;
	switch ( xml->getNodeType() )
	{
		case io::EXML_NODE::EXN_COMMENT:
		case io::EXML_NODE::EXN_CDATA:
		case io::EXML_NODE::EXN_TEXT:
		case io::EXML_NODE::EXN_UNKNOWN:
			return 0;
			break;
		default:
			break;
	}

	// John: Load the node name into memory.
	node.name = new core::stringw(xml->getNodeName());

	// John: Add the pointer to the parent.
	node.parent = parent;

	// John: If the element is empty, it is an important setting.
	// John: If not, it is a special node thingy.
	if ( xml->isEmptyElement() )
	{
		// John: Create settings.
		load_node( xml, &node, NULL );
		xml->read();
	}
	else
	{
		while ( true )
		{
			// John: If we reach the end of this node, we can break out.
			if ( xml->getNodeType() == io::EXML_NODE::EXN_ELEMENT_END )
			{
				// John: Compare the nodes.
				if ( node.name->equals_ignore_case( xml->getNodeName() ) )
				{
					// John: Delete our dynamically allocated array.
					delete node.name;
					node.name = NULL;

					// John: Read the next line of the XML file.
					xml->read();
					return 1;
				}
			}

			// John: If this is non-zero, then we can break out of the loop.
			if ( parse_node( xml, &node, NULL ) )
				break;
		}
	}

	// John: Clean up our memory stuffs!
	delete node.name;
	node.name = NULL;

	return 0;
}

Code: Select all

typedef struct _xmlnode
{
	core::stringw *name;
	struct _xmlnode *parent;
} xmlnode;
Post Reply