sarosar sarosar - 1 year ago 96
iOS Question

XMLParser after parsing gives NULL values in dictionary

I am trying to parse the XML to json format. I use the XMLReader third party library (which downloaded from Github). After Parsing the xml I get the NULL Results.
I tried to print the NSError values which gives the error is "NSErrorDomain code =4 and Document is Empty". What can i do? can any one to help this?

  • Here is my ViewDidLoad () Code:

    NSDictionary *xmlDict = [[NSDictionary alloc]init];

    NSError *parseError = nil;

    xmlDict = [XMLReader dictionaryForXMLString:@"" error:&parseError]; // which call's the XMLReader Class Method

    NSLog(@"MAIN CLASS OF Dictionary: %@",xmlDict); // Gives the NULL Results.

  • Here is my XMLReader.h Code

    #import <Foundation/Foundation.h>

    @interface XMLReader : NSObject <NSXMLParserDelegate>
    NSMutableArray *dictionaryStack;
    NSMutableString *textInProgress;
    NSError *errorPointer;

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


    • Here is my XMLReader.m Code

      #import "XMLReader.h"

      NSString *const kXMLReaderTextNodeKey = @"text";

      @interface XMLReader (Internal)

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


      @implementation XMLReader

      #pragma mark -
      #pragma mark Public methods

      + (NSDictionary *)dictionaryForXMLData:(NSData *)data error:(NSError **)error
      XMLReader *reader = [[XMLReader alloc] initWithError:error];
      NSDictionary *rootDictionary = [reader objectWithData:data];

      return rootDictionary;

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

      #pragma mark Parsing

      - (NSDictionary *)objectWithData:(NSData *)data
      // Clear out any old data

      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 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;
      // 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];
      // 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)
      [dictInProgress setObject:textInProgress forKey:kXMLReaderTextNodeKey];

      // Reset the text

      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;
      NSLog(@"ERROR PONIT IS: %@",errorPointer);


So, In this code i use for parsing the xml data to dictionary format. Can any one to help me on this issue?

Answer Source

Try something like this. Decalre below method in AppDelegate.h file

+(void)downloadDataFromURL:(NSURL *)url withCompletionHandler:(void(^)(NSData *data))completionHandler;

Add the method definition in AppDelegate.m File

+(void)downloadDataFromURL:(NSURL *)url withCompletionHandler:(void (^)(NSData *))completionHandler{
// Instantiate a session configuration object.
      NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];

// Instantiate a session object.
      NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];

// Create a data task object to perform the data downloading.
      NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

    if (error != nil) {
        // If any error occurs then just display its description on the console.
        NSLog(@"%@", [error localizedDescription]);
        // If no error occurs, check the HTTP status code.
        NSInteger HTTPStatusCode = [(NSHTTPURLResponse *)response statusCode];

        // If it's other than 200, then show it on the console.
        if (HTTPStatusCode != 200) {
            NSLog(@"HTTP status code = %d", HTTPStatusCode);

        // Call the completion handler with the returned data on the main thread.
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{

Now Call this method from your viewController like this in viewDidload

[AppDelegate downloadDataFromURL:url withCompletionHandler:^(NSData *data) {
    // Make sure that there is data.
    if (data != nil) {
        xmlDict = [XMLReader dictionaryForXMLData:data error:&parseError];

Hope this will help you

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download