Archive for the ‘NSXMLParser’ Tag

Parsing XML on the iPhone

Since I am developing a game engine that I would like to re-use, I have chosen to host all game data in the form of XML files. There are various reasons for doing this, partly because I can make game editors (Map Editor, Item Editor, NPC Editor, etc) and partly because I value using re-useable code. 

In order to get it all working, I had to explore the NSXMLParser given by the iPhone SDK. With XNA and the .NET framework, I got used to reading in XML in a very specific way, and the iPhone does it quite differently. Currently, my test map’s XML file looks like this:

<?xml version="1.0" encoding="UTF-8"?>
	<MapName>Test Map</MapName>


		<BaseLayer>0, 1, 0, 0, 0, 0, 0, 0, 0</BaseLayer>
		<MiddleLayer>0, 1, 0, 0, 0, 0, 0, 0, 0</MiddleLayer>
		<TopLayer>0, 1, 0, 0, 0, 0, 0, 0, 0</TopLayer>
		<AtmosphereLayer>0, 1, 0, 0, 0, 0, 0, 0, 0</AtmosphereLayer>
		<CollisionLayer>0, 0, 0, 0, 0, 0, 0, 0, 0</CollisionLayer>

In order to read in the XML, there are 3 methods that you need to implement. Since your XML parser goes line by line, you will need to write a method that starts an element, ends an element, and reads a character. Such as:

// Start of element
- (void)parser:(NSXMLParser *)parser 
			didStartElement:(NSString *)elementName 
			namespaceURI:(NSString *)namespaceURI 
			qualifiedName:(NSString *)qName 
			attributes:(NSDictionary *)attributeDict

// Found Character
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSMutableString *)string 

// End Element
- (void) parser:(NSXMLParser *)parser 
			didEndElement:(NSString *)elementName 
			namespaceURI:(NSString *)namespaceURI 
			qualifiedName:(NSString *)qName

Once you have these methods set up, all you really need to do is populate them. For instance, in the “Start Element” method, if your “elementName” = “MapName” (in the above XML case) you would allocate the map classes NSString like so;

mapName = [NSMutableString string];

When you found a character, you would store those into a string, and when the end of the element is reached, you would put that string into whatever element it was reading. For example, the map name:

mapName = stringValueFromFoundCharacter;

Not too hard, but wasn’t easy to figure out either.. At least I know it and now can implement readers for every data that I wish to store as XML!