0

I just did a tutorial on NSXMLParser. What I am completely at a loss at is how NSXMLParser differentiates between different elements. To me it seems undefined.

This is my XML

<?xml version="1.0" encoding="UTF-8"?>
<Prices>
<Price id="1">
<name>Rosie O'Gradas</name>
<Beer>4.50</Beer>
<Cider>4.50</Cider>
<Guinness>4</Guinness>
</Price>
</Prices>

And this is my Parser

-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
if ([elementName isEqualToString:@"Prices"]) {
    app.listArray = [[NSMutableArray alloc] init];
    NSLog(@"The Prices Count");
}
else if ([elementName isEqualToString:@"Price"]) {
    thelist = [[List alloc] init];
    thelist.drinkID = [[attributeDict objectForKey:@"id"]integerValue];
}
}

-(void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if (!currentElementValue) {
    currentElementValue = [[NSMutableString alloc]initWithString:string];

} else {
    [currentElementValue appendString:string];
}

 }

-(void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:@"Prices"]) {
    return;
}
if ([elementName isEqualToString:@"Price"]) {
    [app.listArray addObject:thelist];
    thelist = nil;

} else {
    [thelist setValue:currentElementValue forKey:elementName];
    currentElementValue = nil;
}
 }

I did notice that the names of the Properties in the data object were the same as in the parser. So I understood that at least.

What I am at a loss at is where it assigns these properties their value.

So at the beginning it initializes the data object with

      thelist = [[List alloc] init];

(List is the Data object) But then it does the first thing that I don't understand

     thelist.drinkID = [[attributeDict objectForKey:@"id"]integerValue];

Because it is in an if statement won't it get overwritten every time it finds an id attribute. Or is the 'theList' declaration creating multiple objects?

In the found characters I really have no idea what is going on. As much as I can tell foundCharaters string is every bit of text inside the elements. So current element value is really just a bundle of strings appended together (but I can't tell as for some reason I can't NSLOG it).

From there in the didEndElement section, I wonder if this is the correct interpretation of the code.

    if ([elementName isEqualToString:@"Price"]) {
    [app.listArray addObject:thelist];
    thelist = nil;
    }

I understand that every time that the parser hits the element Price that the app.list array object (declared in another class) has the object added to it 'thelist'.

But here is bit where my lack of understanding in the earlier method takes effect

else {
    [thelist setValue:currentElementValue forKey:elementName];
    currentElementValue = nil;
}

What are they doing here? From what I see the current element value is just a jumble of characters from the XML file. How is it organized? With the Element Name?

One more question (sorry for the length) why isn't the element name case sensitive, I was experimenting and I found it wasn't. Both languages are case sensitive.

Brockman
  • 9
  • 1
  • The purpose of OO programming is to hide what your object does and if you have third party object then we just use them :) never question it lol...the only reason not to question because every single person will come with different implementation ideas which is already done inside NSXMLParser. – TeaCupApp Jun 10 '12 at 13:15
  • I think I need to know what is going on here. Especially the currentElementValue part – Brockman Jun 10 '12 at 13:22

1 Answers1

0

If I interpret your question correctly, it is just about understanding the code which is working fine.

In your XML you have 4 child elements to Price with id=1: name, Beer, Cider and Guinness.

The foundCharacters method will find the characters inside these 4 xml tags, i.e. what is written between <name> and </name>, <Beer> and </Beer>, etc. In your case this is the string Rosie O'Gradas for name, then the string 4.50 for Beer etc.

When characters are found, the method first checks if a container string exists, if not it creates one as currentElementValue. If it does exist, it appends the found characters.

What happens next, logically? It will hit the didEndElement method, in the first case the tag </name>. In this case it will assign the collected text in currentElementValue to the key @"name" and put this key-value pair into the list. The list is of type List, which is defined somewhere else, but it seems to be essentially an NSDictionary.

Because currentElementValue has been stored successfully, it should be destroyed, so the check for its existence next time it hits foundCharacters will work.

Clear?

Mundi
  • 79,884
  • 17
  • 117
  • 140