Reputation: 29
Good Afternoon all ,
I have downloaded data from a web service and im looking to parse that data so that i can use it , but I'm having problems parsing the returned values , below is the aquisition code and anything else in between ANY help would be appreciated
-(IBAction)runNewImport:(id)sender{
recordResults = FALSE;
soapMessage = [NSString stringWithFormat:
@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<s:Envelope \n"
"xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" \n"
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n"
"xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" \n"
"s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" \n"
"xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"> \n"
"<s:Body> \n"
"<[FUNCTION] xmlns=\"http://tempuri.org/\"/>\n"
"</s:Body> \n"
"</s:Envelope>"];
[[NSURLCache sharedURLCache] removeAllCachedResponses];
NSURL *url = [NSURL URLWithString:@"http://[PATH]"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:@"%d", [soapMessage length]];
[theRequest addValue: @"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[theRequest addValue: @"[FUNCTION]" forHTTPHeaderField:@"SOAPAction"];
[theRequest addValue: msgLength forHTTPHeaderField:@"Content-Length"];
[theRequest setHTTPMethod:@"POST"];
[theRequest setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if(theConnection) {
webData = [NSMutableData data];
NSLog(@"%@",webData);
}
else {
NSLog(@"theConnection is NULL");
}
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@"DONE. Received Bytes: %d", [webData length]);
NSString *theXML = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
NSLog(@"THIS IS THE DATA : %@",theXML);
xmlParser = [[NSXMLParser alloc] initWithData: webData];
[xmlParser setDelegate:self];
[xmlParser setShouldResolveExternalEntities: YES];
[xmlParser parse];
}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)
elementName namespaceURI:(NSString *)
namespaceURI qualifiedName:(NSString *)qName
attributes: (NSDictionary *)attributeDict
{
if( [elementName isEqualToString:@"CODE"])
{
soapResults = [[NSMutableString alloc] init];
NSLog(@"%@",soapResults);
recordResults = TRUE;
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)
elementName namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
if( [elementName isEqualToString:@"CODE"])
{
recordResults = FALSE;
soapResults = nil;
}
}
Thanks for looking and again , all help is welcome
Upvotes: 2
Views: 2844
Reputation: 1057
You seem to misunderstand the way NSXMLParser works. I urge you to take a good look at this doc from Apple XML parsing
-(void)parser:didStartElement:namespaceURI:qualifiedName:attributes:
this method is called when the parser finds an opening XML tag like , so it doesn't have any data on it yet. Here, you only need to alloc memory for whatever you want to save
- (void)parser:foundCharacters:
is called when there is data inside a tag which was found in parser:didStartElement:namespaceURI:qualifiedName:attributes:
this is where you store that data first so that you can later save it on the object you want in the next method:
-(void)parser:didEndElement:namespaceURI:qualifiedName
is called when the parser encounters a closing tag (). Now you have the data you kept in a variable in parser:foundCharacters:
and it's time to save it in your object.
EDIT: Alright, lets try and break it down by adding code samples in these methods:
Let's say you have an XML looking like this;
<person>
<lastName>Doe</lastName>
<firstName>John</firstName>
<address>
<street>100 Main Street</street>
<city>Somewhere</city>
</address>
</person>
Naturally, you'd want to have a Person
class with the properties lastName, firstName and addressDictionary containing street and city. And to keep all the Person
s, you'd need personArray.
Now we have the structure, here is the parsing part. Please do note that for the sake of better understanding, I'll be writing each If block separately.
.h file
@property (nonatomic, retain) Person *currentPerson;
@property (nonatomic, retain) NSMutableString *currentElement;
@property (nonatomic, retain) NSMutableDictionary *addressDic; //to be saved to person.addressDictionary when finished
@property (nonatomic, retain) NSMutableArray *personArray;
.m file
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
personArray = [[NSMutableArray alloc] init];
}
- (void) parser: (NSXMLParser *) parser didStartElement: (NSString *) elementName
namespaceURI: (NSString *) namespaceURI qualifiedName: (NSString *) qName attributes: (NSDictionary *) attributeDict
{
if ([elementName isEqualToString:@"Person"])
{
currentPerson = [[Person alloc] init]; //
return;
}
if ([elementName isEqualToString:@"lastName"])
{
currentElement = [[NSMutableString alloc] init];
return;
}
if ([elementName isEqualToString:@"firstName"])
{
currentElement = [[NSMutableString alloc] init];
return;
}
if ([elementName isEqualToString:@"address"])
{
adressDic = [[NSMutableDictionary alloc] init];
return;
}
if ([elementName isEqualToString:@"street"])
{
currentElement = [[NSMutableString alloc] init];
return;
}
if ([elementName isEqualToString:@"city"])
{
currentElement = [[NSMutableString alloc] init];
return;
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
[currentElement appendString:string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:@"Person"])
{
[personArray addObject:currentPerson];
[currentPerson release];
return;
}
if ([elementName isEqualToString:@"lastName"])
{
currentPerson.lastName = currentElement;
[currentElement release]; currentElement = nil;
return;
}
if ([elementName isEqualToString:@"firstName"])
{
currentPerson.firstName = currentElement;
[currentElement release]; currentElement = nil;
return;
}
if ([elementName isEqualToString:@"address"])
{
currentPerson.addressDictionary = addresDic;
[addressDic release];
return;
}
if ([elementName isEqualToString:@"street"])
{
[addressDic setObject:currentElement forKey:@"street"];
[currentElement release]; currentElement = nil;
return;
}
if ([elementName isEqualToString:@"city"])
{
[addressDic setObject:currentElement forKey:@"city"];
[currentElement release]; currentElement = nil;
return;
}
}
When this is all done, parserDidEndDocument:
gets called. Now that you have all the Person
s in your array, do whatever you like with them
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
for (Person *person in personArray)
{
NSLog(@"Person name:%@", person.firstName);
NSLog(@"Person lastname:%@", person.lastName);
}
}
Upvotes: 5