4

Okay i have seen TouchXML, parseXML, NSXMLDocument, NSXMLParser but i am really confused with what to to do.

I have an iphone app which connects to a servers, requests data and gets XML response. Sample xml response to different set of queries is give at http://pastebin.com/f681c4b04

I have another classes which acts as Controller (As in MVC, to do the logic of fetch the data). This class gets the input from the View classes and processes it e.g. send a request to the webserver, gets xml, parses xml, populates its variables (its a singleton/shared Classes), and then responses as true or false to the caller. Caller, based on response given by the controller class, checks controller's variables and shows appropriate contents to the user.

I have the following Controller Class variables:

@interface backendController : NSObject {
NSMutableDictionary *searchResults, *plantInfoResults, *bookmarkList, *userLoginResult;
}

and functions like getBookmarkList, getPlantInfo. Right now i am printing plain XML return by the webserver by NSLog(@"Result: :%@" [NSString stringWithContentsOfURL:url])

I want a generic function which gets the XML returned from the server, parseses it, makes a NSMutableDictionary of it containing XML opening tags' text representation as Keys and XML Tag Values as Values and return that.

Only one question, how to do that?.

Shoaibi
  • 859
  • 2
  • 11
  • 23
  • Still looking forward to how can i use TouchXML to make a generic function that would parse XML at http://pastebin.com/m53d8bf41 , make a dictionary of all things in there with tags as Keys and tag values as Values in it. – Shoaibi Apr 26 '09 at 08:01
  • I was able to fix my problem by http://pastebin.ca/1404334 Feel free to comment... Thanks guys for all the help – Shoaibi Apr 27 '09 at 02:00

3 Answers3

4

Have you tried any of the XML Parsers you mentioned? This is how they set the key value of a node name:

[aBook setValue:currentElementValue forKey:elementName];

P.S. Double check your XML though, seems you are missing a root node on some of your results. Unless you left it out for simplicity.

Take a look at w3schools XML tutorial, it should point you in the right direction for XML syntax.

Kelderic
  • 6,502
  • 8
  • 46
  • 85
Sean
  • 2,453
  • 6
  • 41
  • 53
  • Look at your Results of Fetch Bookmarks, your XML is ... ......In XML you need a node that is the parent to all of your entries: ......... Take a look at the w3schools tutorial, I'll add the link to the answer. – Sean Apr 22 '09 at 11:35
  • Okay i modified the XML, the new XML i the server returns is: http://pastebin.com/m6723d678 which also contains the errors/warnings when executing http://pastebin.com/m3528fa82 . I can't seem to parse XML the normal way using TouchXML. Please help. – Shoaibi Apr 22 '09 at 15:19
  • I think thats coz i am getting 4 blank lines at the start of the XML returned. – Shoaibi Apr 23 '09 at 02:52
  • Also tried with: NSString *r2 = @"460Alcea rosea 'Nigra'Black Hollyhock"; I get the following on Console: 2009-04-23 08:57:06.067 Landscapedia[1926:20b] Starting XML Parsing 2009-04-23 08:57:06.125 Landscapedia[1926:20b] print nodes:( ) No warnings but no data as well, code is same as last pastebin – Shoaibi Apr 23 '09 at 02:58
  • I haven't used TouchXML before, I can try tonight with your XML and see if I get any results. I've used NSXMLParser, the tutorial I put a link to in my answer is pretty simple to follow, I recommend trying that. I'll report back after I try it with your XML. – Sean Apr 23 '09 at 11:40
  • The tutorial link expired. This is the currently working one http://www.iPhoneSDKArticles.com/2008/12/parsing-xml-files.html – Daniel Mar 05 '12 at 17:49
0

providing you one simple example of parsing XML in Table, Hope it would help you.

//XMLViewController.h

#import <UIKit/UIKit.h>
@interface TestXMLViewController : UIViewController<NSXMLParserDelegate,UITableViewDelegate,UITableViewDataSource>{
@private
NSXMLParser *xmlParser;
NSInteger depth;
NSMutableString *currentName;
NSString *currentElement;
NSMutableArray *data;
}
@property (nonatomic, strong) IBOutlet UITableView *tableView;
-(void)start;
@end

//TestXMLViewController.m

#import "TestXmlDetail.h"
#import "TestXMLViewController.h"
@interface TestXMLViewController ()
- (void)showCurrentDepth;

@end

@implementation TestXMLViewController

@synthesize tableView;
- (void)start
{
NSString *xml = @"<?xml version=\"1.0\" encoding=\"UTF-8\" ?><Node><name>Main</name><Node><name>first row</name></Node><Node><name>second row</name></Node><Node><name>third row</name></Node></Node>";
xmlParser = [[NSXMLParser alloc] initWithData:[xml dataUsingEncoding:NSUTF8StringEncoding]];
[xmlParser setDelegate:self];
[xmlParser setShouldProcessNamespaces:NO];
[xmlParser setShouldReportNamespacePrefixes:NO];
[xmlParser setShouldResolveExternalEntities:NO];
[xmlParser parse];

}


- (void)parserDidStartDocument:(NSXMLParser *)parser 
{
NSLog(@"Document started");
depth = 0;
currentElement = nil;
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError 
{
NSLog(@"Error: %@", [parseError localizedDescription]);
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName 
namespaceURI:(NSString *)namespaceURI 
qualifiedName:(NSString *)qName 
attributes:(NSDictionary *)attributeDict
{

currentElement = [elementName copy];

if ([currentElement isEqualToString:@"Node"])
{
    ++depth;
    [self showCurrentDepth];
}
else if ([currentElement isEqualToString:@"name"])
{

    currentName = [[NSMutableString alloc] init];
}
}

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

if ([elementName isEqualToString:@"Node"]) 
{
    --depth;
    [self showCurrentDepth];
}
else if ([elementName isEqualToString:@"name"])
{
    if (depth == 1)
    {
        NSLog(@"Outer name tag: %@", currentName);
    }
    else 
    {
        NSLog(@"Inner name tag: %@", currentName);
      [data addObject:currentName];
    }
    }
   }        

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if ([currentElement isEqualToString:@"name"]) 
{
    [currentName appendString:string];
} 
}

- (void)parserDidEndDocument:(NSXMLParser *)parser 
{
    NSLog(@"Document finished", nil);
}



- (void)showCurrentDepth
{
  NSLog(@"Current depth: %d", depth);
}


- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
 data = [[NSMutableArray alloc]init ];
[self start];
self.title=@"XML parsing";
NSLog(@"string is %@",data);
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
`enter code here`return [data count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = @"Cell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];

if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [data objectAtIndex:indexPath.row];
return cell;
}
@end
Ravi_Parmar
  • 12,319
  • 3
  • 25
  • 36
0

Consider the following code snippet, that uses libxml2, Matt Gallagher's libxml2 wrappers and Ben Copsey's ASIHTTPRequest to parse an HTTP document.

To parse XML, use PerformXMLXPathQuery instead of the PerformHTTPXPathQuery I use in my example.

The nodes instance of type NSArray * will contain NSDictionary * objects that you can parse recursively to get the data you want.

Or, if you know the scheme of your XML document, you can write an XPath query to get you to a nodeContent or nodeAttribute value directly.

ASIHTTPRequest *request = [ASIHTTPRequest alloc] initWithURL:[NSURL URLWithString:@"http://stackoverflow.com/"];
[request start];
NSError *error = [request error];
if (!error) {
    NSData *response = [request responseData];
    NSLog(@"Root node: %@", [[self query:@"//" withResponse:response] description]);
}
else 
    @throw [NSException exceptionWithName:@"kHTTPRequestFailed" reason:@"Request failed!" userInfo:nil];
[request release];

...

- (id) query:(NSString *)xpathQuery withResponse:(NSData *)respData {
    NSArray *nodes = PerformHTMLXPathQuery(respData, xpathQuery);
    if (nodes != nil)
        return nodes;
    return nil;
}
Alex Reynolds
  • 95,983
  • 54
  • 240
  • 345