0

I am creating an XML based application in which I have to fetch data from XML and show on iPhone. I have a url through which the data is being fetched. But I don't know how to create the API method for XML parsing.

How can I create an API method for determining the data returned by the url is in XML format or in JSON format?

halfer
  • 19,824
  • 17
  • 99
  • 186
Rani
  • 3,333
  • 13
  • 48
  • 89
  • As per the official close reason of Too Broad: _Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer_. – halfer Jan 26 '19 at 00:20

6 Answers6

0

You have to use the NSXMLParser

Aravindhan
  • 15,608
  • 10
  • 56
  • 71
0

Look at Apple's XMLPerformance project for sample code.

Alex Reynolds
  • 95,983
  • 54
  • 240
  • 345
  • i understood how to parse xml but the problem is i dont have xml file ,i only have url which will return the xml file .So the problem is i dont know how to check on console the value returned by urland i dont xml element values so that i can start parsing – Rani May 23 '11 at 07:37
0

You don't need to create a custom API. Check out NSXMLParser, and libxml2. Is not bad at this you just have to learn to use it. Once you see the code it should make since

luca590
  • 460
  • 2
  • 5
  • 25
  • NSXMLParser is the fastest and most popular. This should make since – luca590 May 23 '11 at 06:57
  • i understood how to parse xml but the problem is i dont have xml file ,i only have url which will return the xml file .So the problem is i dont know how to check on console the value returned by url. – Rani May 23 '11 at 07:14
  • this is just a thought but couldnt u parse the URL or save it's path as a string and then parse whatever value it returns – luca590 May 24 '11 at 03:37
0

There is a nice tutorial on how you can use the NSXML parser here. You have to implement the parser delegate and get the parsed values from those delegate methods.

You would be basically interested in didStart and didEndelements. A different method is called when the document parsing is over.

Praveen S
  • 10,355
  • 2
  • 43
  • 69
  • i understood how to parse xml but the problem is i dont have xml file ,i only have url which will return the xml file .So the problem is i dont know how to check on console the value returned by url and i dont xml element values so that i can start parsing – Rani May 23 '11 at 07:37
0

Here is the xml parser code I'm using in my projects, it should allow you to parse most XML files :

//
//  XMLParser.h
//

#import <Foundation/Foundation.h>
#import "XMLNode.h"

#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_3_2
@interface XMLParser : NSObject <NSXMLParserDelegate> {
#else
@interface XMLParser : NSObject {
#endif
    XMLNode *rootElement;
    XMLNode *tempElement;
    NSMutableString *temp;
    NSMutableArray *elements;
}

- (NSObject *)parseData:(NSData *)data;

// NSXMLParser delegate implementation
- (void)parserDidStartDocument:(NSXMLParser *)parser;
- (void)parserDidEndDocument:(NSXMLParser *)parser;
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict;
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName;
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;

@end

-

//
//  XMLParser.m
//

#import "XMLParser.h"


@implementation XMLParser

- (NSObject *)parseData:(NSData *)data
{
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
    [parser setDelegate:self];
    [parser setShouldResolveExternalEntities:YES];

    if (![parser parse]) {
        if ([[parser parserError] code] == NSXMLParserUnknownEncodingError) {
            // If encoding is "us-ascii" replace encoding with something known (as NSXMLParser is not supporting this encoding)
            NSString *oldString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
            NSString *newEncodingString = [oldString stringByReplacingOccurrencesOfString:@"encoding=\"us-ascii\"" withString:@"encoding=\"iso-8859-1\"" options:0 range:NSMakeRange(0,100)];
            newEncodingString = [newEncodingString stringByReplacingOccurrencesOfString:@"encoding=\"windows-1251\"" withString:@"encoding=\"iso-8859-1\"" options:0 range:NSMakeRange(0,100)];

            [oldString release];
            NSData *nameData = [newEncodingString dataUsingEncoding:NSASCIIStringEncoding];
            NSXMLParser *parser2 = [[NSXMLParser alloc] initWithData:nameData];
            [parser2 setDelegate:self];
            [parser2 setShouldResolveExternalEntities:YES];
            if (![parser2 parse]) {
                DLog(@"parseXML error : %@",[[parser2 parserError] localizedDescription]);
            }
            [parser2 release];

        } else {
            DLog(@"parseXML error : %@",[[parser parserError] localizedDescription]);
        }

    }
    [parser release];

    return rootElement;
}


- (void)dealloc
{
    if (tempElement != nil) {
        [tempElement release];
    } 
    if (rootElement != nil) {
        [rootElement release];
    }
    if (temp != nil) {
        [temp release];
    }
    if (elements != nil) {
        [elements release];
    }

    [super dealloc];
}


// NSXMLParser delegate implementation


- (void)parserDidStartDocument:(NSXMLParser *)parser
{
    if (elements != nil) {
        [elements release];
    }
    elements = [[NSMutableArray alloc] init];
    if (tempElement != nil) {
        [tempElement release];
        tempElement = nil;
    }
    if (temp != nil) {
        [temp release];
        temp = nil;
    }
    if (rootElement != nil) {
        [rootElement release];
        rootElement = nil;
    }
}


- (void)parserDidEndDocument:(NSXMLParser *)parser
{
   if (elements != nil) {
        [elements release];
        elements = nil;
    }
    if (tempElement != nil) {
        [tempElement release];
        tempElement = nil;
    }
    if (temp != nil) {
        [temp release];
        temp = nil;
    }
}


- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI
 qualifiedName:(NSString *)qualifiedName
    attributes:(NSDictionary *)attributeDict
{
    XMLNode *element = [[[XMLNode alloc] initWithName:elementName] autorelease];
    [element setAttributes:attributeDict];
    if (tempElement != nil) {
        [tempElement addChild:element];
        [elements addObject:tempElement];
        [tempElement release];
    } else {
        rootElement = [element retain];
    }

    tempElement = [element retain];
    if (temp != nil) {
        [temp release];
    }
    temp = [[NSMutableString alloc] init];
}


- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI
 qualifiedName:(NSString *)qName
{
    [tempElement setContent:temp];
    [temp release];
    temp = nil;
    [tempElement release];
    tempElement = nil;
    if ([elements count] > 0) {
        tempElement = [[elements lastObject] retain];
        [elements removeLastObject];
    }
}


- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    if (temp != nil) {
        [temp appendString:string];
    }
}

@end

-

//
//  XMLNode.h
//

#import <Foundation/Foundation.h>

/**
 * XMLNode represents an XML data node.
 *
 * Every node can contain multiple childs, attributes, a content string
 * and an element name. An XML document is represented using a reference
 * to the document root node.
 * @ingroup Webservice
 */
@interface XMLNode : NSObject {

    NSMutableArray *childs;
    NSDictionary *attributes;
    NSString *content;
    NSString *elementName;

}

/**
 * Return an initialized XMLNode.
 * @param name The element name of the node.
 */
- (id)initWithName:(NSString *)name;

/**
 * Set the node attributes.
 * @param dictionary A dictionary containing the attributes.
 */
- (void)setAttributes:(NSDictionary *)dictionary;

/**
 * Set the content as string.
 * @param string The content as string.
 */
- (void)setContent:(NSString *)string;

/**
 * Add a child node.
 * @param xmlElement The child node.
 */
- (void)addChild:(XMLNode *)xmlElement;

/**
 * Return a specific attribute.
 * @param name The attribute name.
 * @return The attribute for the specified name or nil.
 */
- (NSString *)attributeForName:(NSString *)name;

/**
 * Return a child at a specific index.
 * 
 * If the index is out of the bounds, an NSRangeException is thrown.
 * @param index The position of the child (by document order).
 * @return The child at index
 * @see childElementsCount
 */
- (XMLNode *)childElementAtIndex:(int)index;

/**
 * Return a child with a certain name.
 * @param name The name of the element.
 * @return The element or nil if not available.
 */
- (XMLNode *)childWithName:(NSString *)name;
- (XMLNode *)childWithName:(NSString *)name atIndex:(NSInteger)index;

/** 
 * Return the number of child nodes.
 * @return The number of child nodes.
 */
- (int)childElementsCount;
- (int)childWithNameElementsCount:(NSString *)name;

/** 
 * Return the node content.
 * @return The node content as string.
 */
- (NSString *)content;

/**
 * Get the name of the xml element.
 * @return The name of the element.
 */
- (NSString *)name;

- (void)dealloc;

@end

-

//
//  XMLNode.m
//

#import "XMLNode.h"


@implementation XMLNode
- (id)initWithName:(NSString *)name
{
    self = [super init];
    elementName = [name copy];
    childs = [[NSMutableArray alloc] init];
    return self;
}


- (void)setAttributes:(NSDictionary *)dictionary
{
    if (attributes != nil) {
        [attributes release];
    }
    attributes = [dictionary retain];
}


- (void)setContent:(NSString *)string
{
    if (content != nil) {
        [content release];
    }
    content = [string retain];
}

- (void)addChild:(XMLNode *)xmlElement
{
    [childs addObject:xmlElement];
}


- (NSString *)attributeForName:(NSString *)name
{
    return [attributes objectForKey:name];
}


- (XMLNode *)childElementAtIndex:(int)index
{
    return [childs objectAtIndex:index];
}


- (XMLNode *)childWithName:(NSString *)name
{
    int i;
    for (i=0; i<[childs count]; ++i) {
        XMLNode *child = [childs objectAtIndex:i];
        if ([[[child name] lowercaseString] isEqualToString:[name lowercaseString]]) {
            return child;
        }
    }

    return nil;
}

- (XMLNode *)childWithName:(NSString *)name atIndex:(NSInteger)index
{
    int i;
    int count = 0;
    for (i=0; i<[childs count]; ++i) {
        XMLNode *child = [childs objectAtIndex:i];
        if ([[[child name] lowercaseString] isEqualToString:[name lowercaseString]]) {
            if (count == index)
                return child;
            count ++;
        }
    }

    return nil;
}

- (int)childElementsCount
{
    return [childs count];
}

- (int)childWithNameElementsCount:(NSString *)name
{
    int i;
    int count = 0;
    for (i=0; i<[childs count]; ++i) {
        XMLNode *child = [childs objectAtIndex:i];
        if ([[[child name] lowercaseString] isEqualToString:[name lowercaseString]]) {
            count ++;
        }
    }

    return count;
}


- (NSString *)content
{
    return content;
}


- (NSString *)name
{
    return elementName;
}


- (void)dealloc
{
    if (content != nil) {
        [content release];
    }
    if (childs != nil) {
        [childs release];
    }
    if (attributes != nil) {
        [attributes release];
    }

    [super dealloc];
}

@end

use this as following (this sample is to analyze a rss feed :

XMLParser *parser = [[XMLParser alloc] init];
NSObject *rss = [parser parseData:rssFeed];
feedItems = [(XMLNode *)rss childWithName:@"channel"];
if (feedItems) {
    NSLog(@"%@",[[feedItems childWithName:@"title"] content]);
}
[parser release];

Check XMLNode.h for more methods if you need a more complex analysis

Sylverb
  • 939
  • 6
  • 14
0

It sounds like your question is not how to parse XML, but how to download an XML document from the web into an NSData object, or the like.

You can use the open source ASIHTTPRequest framework to quickly download your XML data. Take a look at the how-to document on setting up an asynchronous request.

Assuming the URL is correct and the request is successful, the XML data will be stored in the request's responseData property.

You can then use various methods for parsing the XML data in this property. I recommend libxml2, as it is the fastest. But you could use whatever parser engine and method you want, at this point.

Alex Reynolds
  • 95,983
  • 54
  • 240
  • 345