Parsing XML element attributes with TouchXML

Assuming that you already familiar with parsing XML with a little help from TouchXML we will go straight to the topic: parsing an attribute! I’ll just put some “sample” XML here so it would be easier to understand what’s happening in code later.

<pigletlist>
<piglet id="1">
    <name>Nifnif</name>
</piglet>
<piglet id="2">
    <name>Nufnuf</name>
</piglet>
<piglet id="3">
    <name>Nafnaf</name>
</piglet>
</pigletlist>

Well, here we have our tree little piglets put in a single XML file and bellow lies the magic code which parses piglet list with their id attributes. If you are too lazy to look trough all the code (I would be), key point is attributeForName method of CXMLElement object used like this: [[node attributeForName:@"id"] stringValue].

	//	we will put parsed data in an a array
	NSMutableArray *res = [[NSMutableArray alloc] init];

	//	using local resource file
	NSString *XMLPath	= [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"piglets.xml"];
	NSData *XMLData		= [NSData dataWithContentsOfFile:XMLPath];
    CXMLDocument *doc	= [[[CXMLDocument alloc] initWithData:XMLData options:0 error:nil] autorelease];

	NSArray *nodes = NULL;
	//	searching for piglet nodes
	nodes = [doc nodesForXPath:@"//piglet" error:nil];

	for (CXMLElement *node in nodes) {
		NSMutableDictionary *item = [[NSMutableDictionary alloc] init];
		int counter;
		for(counter = 0; counter < [node childCount]; counter++) {
			//	common procedure: dictionary with keys/values from XML node
			[item setObject:[[node childAtIndex:counter] stringValue] forKey:[[node childAtIndex:counter] name]];
		}

		//	and here it is - attributeForName! Simple as that.
		[item setObject:[[node attributeForName:@"id"] stringValue] forKey:@"id"];  // <------ this magical arrow is pointing to the area of interest

		[res addObject:item];
		[item release];
	}

	//	and we print our results
	NSLog(@"%@", res);
	[res release];

Our results:

2010-02-05 09:54:01.078 demo[1901:207] (
        {
        id = 1;
        name = Nifnif;
    },
        {
        id = 2;
        name = Nufnuf;
    },
        {
        id = 3;
        name = Nafnaf;
    }
)

Mysterious "text = \n"

Sorry, that my example caused frustration to everyone, I used cleaner XML than the posted one and let it be a lesson for me that I should post everything as it is. Anyway, cleaning all the white spaces and new lines from XML file is not an option for everyone, so the only solution I can think of would be to check if value for some key is empty.

NSString * value = [[[node childAtIndex:counter] stringValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
 if ([value length] != 0){
[item setObject:[[node childAtIndex:counter] stringValue] forKey:[[node childAtIndex:counter] localName]];

}

Of course if your XML has "text" key and it can be empty - you should check for that too.

I hope this clears some things.

Tags: , , , ,

26 responses

  1. Jon Dack
    Posted April 6, 2010 at 19:36 | Permalink

    This is very helpful, however what if the attribute was in a child node?

    I have been unable to get to these attributes

    Nifnif

    Nufnuf

  2. Posted April 15, 2010 at 16:07 | Permalink

    Great post!

    Mind if I use it and the installation post (with attribution) as part of the official TouchXML documentation?

    • Foobar Pig
      Posted April 18, 2010 at 16:20 | Permalink

      Thanks! And, of course, I wouldn’t mind at all!

  3. Posted April 16, 2010 at 05:39 | Permalink

    Is anyone else getting a compiler warning “warning: no ‘-attributeForName:’ method found” when they use the attributeForName method ?

  4. Joe
    Posted May 7, 2010 at 01:44 | Permalink

    Great tutorial!

    I am getting an extra key with the name of “text” and the value of “\n” when I run the example code.. any ideas on why this would be happening ?

  5. Posted June 1, 2010 at 11:20 | Permalink

    For me too!

    • Posted June 29, 2010 at 22:17 | Permalink

      did u guys solve the issue with extra key with the name of “text” and the value of “\n”

      • Foobar Pig
        Posted June 30, 2010 at 20:29 | Permalink

        Hi,

        I’ve updated my post with some kind of workaround for that issue.

        			NSString * value = [[[node childAtIndex:counter] stringValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
        			if ([value length] != 0){
        				[item setObject:[[node childAtIndex:counter] stringValue] forKey:[[node childAtIndex:counter] localName]];
        			}
        
  6. Posted June 4, 2010 at 11:46 | Permalink

    Thanks, very useful article

  7. mattyohe
    Posted June 27, 2010 at 23:46 | Permalink

    For the folks with the \n text attributes, you have carriage returns in your XML.

  8. Posted June 29, 2010 at 18:27 | Permalink

    sorry… how can i delete my previous
    i m trying to show the xml nodes with the “text” element

    employee
    name>John Director Job description here ...

  9. Foobar Pig
    Posted June 30, 2010 at 20:31 | Permalink

    Workaround for the “\n” value for “text” key:

    			NSString * value = [[[node childAtIndex:counter] stringValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    			if ([value length] != 0){
    				[item setObject:[[node childAtIndex:counter] stringValue] forKey:[[node childAtIndex:counter] localName]];
    			}
    

    Sorry that I’ve caused this mess.

  10. TheraCoder
    Posted July 14, 2010 at 11:30 | Permalink

    Hi, It’s possible to use this if teh exact XML of what we are handling is known. If its to be generated by using a wsdl could you pls give suggestions to a proper client stub generator for SOAP WSDLs.
    any help would be highly appreciated
    thanks

  11. mapedd
    Posted August 4, 2010 at 12:00 | Permalink

    Hi, deat author, can yoo look here :
    http://stackoverflow.com/questions/3404515/parsing-soap-response-with-touchxml-a-problem
    and maybe help me with yout framework?
    thanks for any help

  12. Erril
    Posted September 12, 2010 at 19:42 | Permalink

    You guys are lucky. I can’t even get this stuff to compile.

  13. Shahid
    Posted January 10, 2011 at 16:06 | Permalink

    Hey,
    Thx man very nice and easy !

  14. alper
    Posted February 11, 2011 at 15:08 | Permalink

    Hello,

    How can i parsing this xml file ?

    11.02.2011
    12.02.2011

  15. Posted April 4, 2011 at 23:49 | Permalink

    I noticed that the bounce rate on my web sites is pretty high – for most visits it is 100%. I believe my content is relevant to the key phrases I’m found for. What do you think may be the issue?. What exactly is a normal bounce rate for you?! Help !!

  16. Arun
    Posted May 24, 2011 at 13:14 | Permalink

    Can u help me……………

    How can parsing the selected subchildnodes in xml file

    xml file:

    http://maps.googleapis.com/maps/api/geocode/xml?address=Alangayam,635701,Vellore,Tamilnadu,India&sensor=false

    In that i want to parse the formatted_address

    latitude and longitude From geometry…

  17. Arun
    Posted May 24, 2011 at 13:49 | Permalink

    how to parsing the different childnodes in given xml file

  18. Umaid
    Posted July 4, 2011 at 11:18 | Permalink
  19. Chris
    Posted August 28, 2012 at 23:24 | Permalink

    I would hug you if I could. Thanks so much!

Leave a Reply