0

I'm having XML in my Web-Service in following format.

<xml>
    <Menu>
        <pair>
            <MenuCategory shortname="Starters Menu" description_en="hgfhghgh" image="Small.jpg" description_fr="" description_ge="" description_it="" description_sp="" description_ch="">
                <MenuItems>
                    <menuItem price="666" image="060649XSmall.jpg" shortname="kandan" description_en="kandan" description_fr="" description_ge="" description_it="" description_sp="" description_ch=""/>
                    <menuItem price="250" image="3.jpg" shortname="Vegetable Soups" description_en="Vegetable Soups" description_fr="" description_ge="" description_it="" description_sp="" description_ch=""/>
                    <menuItem price="52" image="3.jpg" shortname="Mixed Starters" description_en="Mixed Starters" description_fr="" description_ge="" description_it="" description_sp="" description_ch=""/>
                    <menuItem price="45" image="14.jpg" shortname="Pumpkin soup" description_en="Pumpkin soup" description_fr="" description_ge="" description_it="" description_sp="" description_ch=""/>
                    <menuItem price="15" image="15.jpg" shortname="Almondrolledgoatsche" description_en="Almondrolledgoatsche" description_fr="" description_ge="" description_it="" description_sp="" description_ch=""/>
                </MenuItems>
            </MenuCategory>
        </pair>
    </Menu>
</xml>

I've tried to parse this XML from my webservice using TBXML. But, not yet get my output,

TBXML *XML = [[TBXML alloc]initWithURL:[NSURL URLWithString:urlString]];
TBXMLElement *rootXML = XML.rootXMLElement;
TBXMLElement *e = [TBXML childElementNamed:@"MenuItems" parentElement:rootXML];
NSString *woeid = [TBXML textForElement:e->firstChild];
NSLog(@"Woeid - %@", woeid);    

It throws EXEC_BAD_ACCESS error simply. I just required to parse this xml to my NSMutableArray There are lot of examples related to this. But, don't know which one is suitable for my requirement. Has anyone worked in this format? Any idea that how to achieve that?

3
  • @MidhunMP It simply gives null. Commented Mar 6, 2013 at 6:00
  • @pravenn: can you NSLog the rootXML ? Commented Mar 6, 2013 at 6:08
  • @MidhunMP EXEC_Bad_Access error Commented Mar 6, 2013 at 6:16

5 Answers 5

1

You can use XMLReader files to parse xml data to NSDictionary or NSArray or MutableArray. using it as :

NSError *error=nil;

NSString *responseString=[NSString stringWithFormat:@"<xml><Menu><pair><MenuCategory shortname=\"Starters Menu\" description_en=\"hgfhghgh\" image=\"Small.jpg\" description_fr=\"\" description_ge=\"\" description_it=\"\" description_sp=\"\" description_ch=\"\"><MenuItems><menuItem price=\"666\" image=\"060649XSmall.jpg\" shortname=\"kandan\" description_en=\"kandan\" description_fr=\"\" description_ge=\"\" description_it=\"\" description_sp=\"\" description_ch=\"\"/><menuItem price=\"250\" image=\"3.jpg\" shortname=\"Vegetable Soups\" description_en=\"Vegetable Soups\" description_fr=\"\" description_ge=\"\" description_it=\"\" description_sp=\"\" description_ch=\"\"/><menuItem price=\"52\" image=\"3.jpg\" shortname=\"Mixed Starters\" description_en=\"Mixed Starters\" description_fr=\"\" description_ge=\"\" description_it=\"\" description_sp=\"\" description_ch=\"\"/><menuItem price=\"45\" image=\"14.jpg\" shortname=\"Pumpkin soup\" description_en=\"Pumpkin soup\" description_fr=\"\" description_ge=\"\" description_it=\"\" description_sp=\"\" description_ch=\"\"/><menuItem price=\"15\" image=\"15.jpg\" shortname=\"Almondrolledgoatsche\" description_en=\"Almondrolledgoatsche\" description_fr=\"\" description_ge=\"\" description_it=\"\" description_sp=\"\" description_ch=\"\"/></MenuItems></MenuCategory></pair></Menu></xml>"];

NSDictionary *dictionary=[XMLReader dictionaryForXMLString:responseString error:&error];

NSLog(@"dictioanry is %@",dictionary);

NSMutableArray *menuItemsArray=[[NSMutableArray alloc] initWithArray:[[[[[[dictionary valueForKey:@"xml"] valueForKey:@"Menu"] valueForKey:@"pair"] valueForKey:@"MenuCategory"] valueForKey:@"MenuItems"] valueForKey:@"menuItem"]];

NSLog(@"menu item array is %@",menuItemsArray);

Console Log:--------

    dictioanry is {
    xml =     {
        Menu =         {
            pair =             {
                MenuCategory =                 {
                    MenuItems =                     {
                        menuItem =                         (
                                                        {
                                "description_ch" = "";
                                "description_en" = kandan;
                                "description_fr" = "";
                                "description_ge" = "";
                                "description_it" = "";
                                "description_sp" = "";
                                image = "060649XSmall.jpg";
                                price = 666;
                                shortname = kandan;
                            },
                                                        {
                                "description_ch" = "";
                                "description_en" = "Vegetable Soups";
                                "description_fr" = "";
                                "description_ge" = "";
                                "description_it" = "";
                                "description_sp" = "";
                                image = "3.jpg";
                                price = 250;
                                shortname = "Vegetable Soups";
                            },
                                                        {
                                "description_ch" = "";
                                "description_en" = "Mixed Starters";
                                "description_fr" = "";
                                "description_ge" = "";
                                "description_it" = "";
                                "description_sp" = "";
                                image = "3.jpg";
                                price = 52;
                                shortname = "Mixed Starters";
                            },
                                                        {
                                "description_ch" = "";
                                "description_en" = "Pumpkin soup";
                                "description_fr" = "";
                                "description_ge" = "";
                                "description_it" = "";
                                "description_sp" = "";
                                image = "14.jpg";
                                price = 45;
                                shortname = "Pumpkin soup";
                            },
                                                        {
                                "description_ch" = "";
                                "description_en" = Almondrolledgoatsche;
                                "description_fr" = "";
                                "description_ge" = "";
                                "description_it" = "";
                                "description_sp" = "";
                                image = "15.jpg";
                                price = 15;
                                shortname = Almondrolledgoatsche;
                            }
                        );
                    };
                    "description_ch" = "";
                    "description_en" = hgfhghgh;
                    "description_fr" = "";
                    "description_ge" = "";
                    "description_it" = "";
                    "description_sp" = "";
                    image = "Small.jpg";
                    shortname = "Starters Menu";
                };
            };
        };
    };
}

2013-03-06 11:52:31.500 MobileTrading[1212:11303] menu item array is (
        {
        "description_ch" = "";
        "description_en" = kandan;
        "description_fr" = "";
        "description_ge" = "";
        "description_it" = "";
        "description_sp" = "";
        image = "060649XSmall.jpg";
        price = 666;
        shortname = kandan;
    },
        {
        "description_ch" = "";
        "description_en" = "Vegetable Soups";
        "description_fr" = "";
        "description_ge" = "";
        "description_it" = "";
        "description_sp" = "";
        image = "3.jpg";
        price = 250;
        shortname = "Vegetable Soups";
    },
        {
        "description_ch" = "";
        "description_en" = "Mixed Starters";
        "description_fr" = "";
        "description_ge" = "";
        "description_it" = "";
        "description_sp" = "";
        image = "3.jpg";
        price = 52;
        shortname = "Mixed Starters";
    },
        {
        "description_ch" = "";
        "description_en" = "Pumpkin soup";
        "description_fr" = "";
        "description_ge" = "";
        "description_it" = "";
        "description_sp" = "";
        image = "14.jpg";
        price = 45;
        shortname = "Pumpkin soup";
    },
        {
        "description_ch" = "";
        "description_en" = Almondrolledgoatsche;
        "description_fr" = "";
        "description_ge" = "";
        "description_it" = "";
        "description_sp" = "";
        image = "15.jpg";
        price = 15;
        shortname = Almondrolledgoatsche;
    }
)
Sign up to request clarification or add additional context in comments.

6 Comments

Hi. My xml data are on website. How to get that from there first?
With NSMUtableURLRequest?
check my another answer I have just uploaded will get data using NSMutableURLRequest
Yes. I got the response in Dictionary format. But, it doesn't converted into NSMutableArray
If you got it in dictionary format then simply get valueForKey as I have mentioned in previous answer.
|
1

@Praveen read attribute instead of elements

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

Comments

1

I thing the following code might help you. And you have made good choice of choosing TBXML for xml parsing..

in .h file

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController<NSXMLParserDelegate>

 {
NSMutableArray *dictionaryStack;
NSMutableString *textInProgress;
NSError **errorPointer;
}

+ (NSDictionary *)dictionaryForXMLData:(NSData *)data error:(NSError **)errorPointer;
+ (NSDictionary *)dictionaryForXMLString:(NSString *)string error:(NSError **)errorPointer;

@end

in .m file

NSString *const kXMLReaderTextNodeKey = @"text";

@interface ViewController ()

- (id)initWithError:(NSError **)error;
- (NSDictionary *)objectWithData:(NSData *)data;

@end

@implementation ViewController

- (void)viewDidLoad{


NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"Your URL Here"]];

NSError *parseError = nil;
NSDictionary *xmlDictionary = [ViewController dictionaryForXMLData:data error:&parseError];    // Print the dictionary

NSLog(@"%@",xmlDictionary);



}


+ (NSDictionary *)dictionaryForXMLData:(NSData *)data error:(NSError **)error
{   
ViewController *reader = [[ViewController alloc] initWithError:error];
NSDictionary *rootDictionary = [reader objectWithData:data];
[reader release];
return rootDictionary;
}

 + (NSDictionary *)dictionaryForXMLString:(NSString *)string error:(NSError **)error
{ 
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
return [ViewController dictionaryForXMLData:data error:error];
}


- (id)initWithError:(NSError **)error
{
if (self = [super init])
{
    errorPointer = error;
}
return self;
}

- (void)dealloc
{
[dictionaryStack release];
[textInProgress release];
[super dealloc];
}

- (NSDictionary *)objectWithData:(NSData *)data
{
// Clear out any old data
[dictionaryStack release];
[textInProgress release];

dictionaryStack = [[NSMutableArray alloc] init];
textInProgress = [[NSMutableString alloc] init];

// Initialize the stack with a fresh dictionary
[dictionaryStack addObject:[NSMutableDictionary dictionary]];

// Parse the XML
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
parser.delegate = self;
BOOL success = [parser parse];

// Return the stack’s root dictionary on success
if (success)
{
    NSDictionary *resultDict = [dictionaryStack objectAtIndex:0];
    return resultDict;
}

return nil;
}

#pragma mark -
#pragma mark NSXMLParserDelegate methods

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
// Get the dictionary for the current level in the stack
NSMutableDictionary *parentDict = [dictionaryStack lastObject];

// Create the child dictionary for the new element, and initilaize it with the attributes
NSMutableDictionary *childDict = [NSMutableDictionary dictionary];
[childDict addEntriesFromDictionary:attributeDict];

// If there’s already an item for this key, it means we need to create an array
id existingValue = [parentDict objectForKey:elementName];
if (existingValue)
{
    NSMutableArray *array = nil;
    if ([existingValue isKindOfClass:[NSMutableArray class]])
    {
        // The array exists, so use it
        array = (NSMutableArray *) existingValue;
    }
    else
    {
        // Create an array if it doesn’t exist
        array = [NSMutableArray array];
        [array addObject:existingValue];

        // Replace the child dictionary with an array of children dictionaries
        [parentDict setObject:array forKey:elementName];
    }

    // Add the new child dictionary to the array
    [array addObject:childDict];
}
else
{
    // No existing value, so update the dictionary
    [parentDict setObject:childDict forKey:elementName];
}

// Update the stack
[dictionaryStack addObject:childDict];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
// Update the parent dict with text info
NSMutableDictionary *dictInProgress = [dictionaryStack lastObject];

// Set the text property
if ([textInProgress length] > 0)
{
    // Get rid of leading + trailing whitespace
    [dictInProgress setObject:textInProgress forKey:kXMLReaderTextNodeKey];

    // Reset the text
    [textInProgress release];
    textInProgress = [[NSMutableString alloc] init];
}

// Pop the current dict
[dictionaryStack removeLastObject];
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
// Build the text value
[textInProgress appendString:string];
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
// Set the error pointer to the parser’s error object
*errorPointer = parseError;
}


@end

Hope this Helps!!!

Comments

0

Get Data from URL using NSMutableRequest

    NSString *stringURL=[NSString stringWithFormat:@"http://yourURL"];
NSURL *url=[NSURL URLWithString:stringURL];

NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];
NSError *error;

NSURLResponse *response;

NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

NSString *responseString=[[NSString alloc] initWithData:urlData encoding:NSUTF8StringEncoding];

NSDictionary *dictionary=[XMLReader dictionaryForXMLString:responseString error:&error];

Comments

0

If you want to use NSXMLParser then use it.

- (void)viewDidLoad

   {
      NSURL *url = [[NSURL alloc]initWithString:@"yourURL"];
        NSXMLParser *parser = [[NSXMLParser alloc]initWithContentsOfURL:url];
        [parser setDelegate:self];
       BOOL result = [parser parse];
   }

    - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
    {
        NSLog(@"Did start element");
       if ( [elementName isEqualToString:@"root"])
        {
          NSLog(@"found rootElement");
          return;
        }
    }

    - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
    {
        NSLog(@"Did end element");
        if ([elementName isEqualToString:@"root"]) 
            {
              NSLog(@"rootelement end");
            }

    }
    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
    {

       if([currentElementName isEqualToString:@"column"])
      {
           NSLog(@"Value %@",string);
      }

    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.