0

I want to retrieve elements that are parsed in a NSMutableArray and store them into a NSString variable and then store them in NSMutableArray as NSString (because I want to display the content in a NSComboBox). I tried this but it dosen't work. Can you fix the problem, I can't fix it:

//--this is the parsing code : 
- (void)parser:(NSXMLParser *)parser 
didStartElement:(NSString *)elementName 
  namespaceURI:(NSString *)namespaceURI 
 qualifiedName:(NSString *)qualifiedName 
    attributes:(NSDictionary *)attributeDict {

    if ([elementName isEqualToString:@"user"]) {
        NSLog(@"user element found – create a new instance of User class...");
        if(currentElementValue == nil)
            currentElementValue = [NSMutableString string];
        else 
            [currentElementValue setString:@""];
    }
    else {
        currentElementValue = nil;
    }
        user = [[User alloc] init];


}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    if (!currentElementValue) {
        // init the ad hoc string with the value     
        currentElementValue = [[NSMutableString alloc] initWithString:string];
    } else {
        // append value to the ad hoc string    
        [currentElementValue appendString:string];
        if (currentElementValue) 
        {
            currentElementValue = nil;
        }
    }
    NSLog(@"Processing value for : %@", string);
}  

- (void)parser:(NSXMLParser *)parser 
 didEndElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI 
 qualifiedName:(NSString *)qName {

    if ([elementName isEqualToString:@"users"]) {
        // We reached the end of the XML document
        return;
        NSLog(@"QUIT");
    }
    if ([elementName isEqualToString:@"userName"]) {
        [[self user] setUserName:currentElementValue];
        NSLog(@"final step for value: %@", user.userName);
        NSLog(@"currentElementName content : %@", currentElementValue);
        [currentElementValue release];
        NSLog(@"release : %@", currentElementValue);
        currentElementValue = nil;
        NSLog(@"release : %@", currentElementValue);
    }
    if ([elementName isEqualToString:@"firstName"]) {
        [[self user] setFirstName:currentElementValue];
        [currentElementValue release];
        currentElementValue = nil;
    }

    if ([elementName isEqualToString:@"lastName"]) {
        [[self user] setLastName:currentElementValue];
        [currentElementValue release];
        currentElementValue = nil;
    }

    if ([elementName isEqualToString:@"user"]) {
        NSLog(@"\n user=%@ \n",user);

        [users addObject:user];
        NSLog(@"userName test : %@", users);

        [user release];
        user = nil;
    }
}
-(BOOL)parseDocumentWithData:(NSData *)data {

    if (data == nil)
        return NO;
    NSXMLParser *xmlparser = [[NSXMLParser alloc] initWithData:data];
    [xmlparser setDelegate:self];
    [xmlparser setShouldResolveExternalEntities:NO];

    BOOL ok = [xmlparser parse];
    if (ok == NO)
        NSLog(@"error");
    else
        NSLog(@"OK");

    [xmlparser release];
    return ok;
}

// this is the xml file : 

<users>
 <user>
  <userName>mspeller</userName>
  <firstName>Mike</firstName>
  <lastName>Speller</lastName>
 </user>
 <user>
  <userName>mgdan</userName>
  <firstName>Mila</firstName>
  <lastName>Gdan</lastName>
 </user>

</users>


//-------
NSMutableArray *tabletest= [[NSMutableArray alloc] init];
NSMutableString * result = [[NSMutableString alloc] init];
int i;
for(i=0; i < [users count]; i++){

    [result appendString:[NSString stringWithFormat:@"%@",[[users objectAtIndex:i] valueForKey:@"userName"]] ];
    NSLog(@"result==%@",result);

    [tabletest addObject:result];
}
Wael
  • 71
  • 5

2 Answers2

0

Based on your link in the comment section I think you're accessing the "userName" property the wrong way. You're trying to access it, as users contains NSDictionary objects. As far as I can see you're adding User objects to the NSMutableArray.

Try the following (I took the liberty to beautify the code a bit):

NSMutableArray *tabletest= [NSMutableArray array];

for (User* user in users)
{
    NSString* result = [NSString stringWithFormat:@"%@", user.userName];
    NSLog(@"result==%@",result);

    [tabletest addObject:result];
}

Please correct me if I totally misunderstood your design.

ThomasCle
  • 6,792
  • 7
  • 41
  • 81
  • thanks , I found that the parsing code does store only the last element ( latName ) of each userthat's why it couldn't be displayed . Can you help me to fix this – Wael Jul 17 '12 at 09:08
  • I will need to see some of the XML you are parsing. Could you please post the XML and the parser code on this question (not the other you linked in the comment section of the question). You can edit your question and put more code into it - there's no need to post a new question :-) – ThomasCle Jul 17 '12 at 09:15
  • 1
    This code is much cleaner than that in the question but it does exactly the same thing except for fixing the bug with result being appended to each time. `-valueForKey:` uses the property if the property exists. – JeremyP Jul 17 '12 at 09:17
  • Note also that `tabletest = [users valueForKey: @"userName"]` is pretty much the same as your whole loop except that the final array is immutable. – JeremyP Jul 17 '12 at 09:19
  • @JeremyP Oh thanks for correcting that. I actually didn't know that :) – ThomasCle Jul 17 '12 at 09:20
  • Helloo do you see the problem? – Wael Jul 17 '12 at 10:06
  • @Cupcake Can you help me pleasz – Wael Jul 17 '12 at 10:19
0

I don't follow what your intention is, but what your code does at the moment is add the same string [user count] time to the array tabletest as follows:

The line:

[result appendString:[NSString stringWithFormat:@"%@",[[users objectAtIndex:i] valueForKey:@"userName"]] ];

accumulates into result the result of appending each [[users objectAtIndex:i] valueForKey:@"userName"] together - each iteration of the loop adds the next item to the end of result.

The line:

[tabletest addObject:result];

Adds the object referenced by result into the array. This is done once per iteration so the array ends up with [users count] references to the same object. Placing a reference to a mutable string into an array does not place a copy of its current value, just a reference to the string - mutate the string and the mutation is visible through the reference stored in the array.

So the final result of your code is an array of [users count] references to the same mutable string, and that string is the concatenation of all the [[users objectAtIndex:i] valueForKey:@"userName"] values.

What was your intent?

If you are trying to create an array of string representations of [[users objectAtIndex:i] valueForKey:@"userName"] then change the code to:

NSMutableArray *tabletest= [[NSMutableArray alloc] init];

for(int i = 0; i < [users count]; i++)
{
   // create a string representation of userName
   NSString *result = [NSString stringWithFormat:@"%@",[[users objectAtIndex:i] objectForKey:@"userName"]];
   // add the string to the array
   [tabletest addObject:result];
}

But maybe your intent is something else?

CRD
  • 52,522
  • 5
  • 70
  • 86
  • thanks , I found that the parsing code does store only the last element ( latName ) of each userthat's why it couldn't be displayed . Can you help me to fix this – Wael Jul 17 '12 at 09:25