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: CXMLDocument, CXMLElement, iphone-dev, TouchXML, xml
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
Great post!
Mind if I use it and the installation post (with attribution) as part of the official TouchXML documentation?
Thanks! And, of course, I wouldn’t mind at all!
Is anyone else getting a compiler warning “warning: no ‘-attributeForName:’ method found” when they use the attributeForName method ?
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 ?
Same problem here!
For me too!
did u guys solve the issue with extra key with the name of “text” and the value of “\n”
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]]; }Thanks, very useful article
For the folks with the \n text attributes, you have carriage returns in your XML.
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 ...
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.
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
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
You guys are lucky. I can’t even get this stuff to compile.
Hey,
Thx man very nice and easy !
Hello,
How can i parsing this xml file ?
11.02.2011
12.02.2011
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 !!
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…
how to parsing the different childnodes in given xml file
How to parse http://weather.yahooapis.com/forecastrss?w=1940345&u=c
I would hug you if I could. Thanks so much!