解析后的XMLParser在字典中给出NULL值

时间:2016-06-13 11:24:07

标签: ios objective-c json xml xml-parsing

我正在尝试将XML解析为json格式。我使用XMLReader第三方库(从Github下载)。解析xml后,我得到NULL结果。  我试图打印NSError值,错误是“NSErrorDomain code = 4而Document is Empty”。我能做什么?任何人都可以帮忙吗?

  • 这是我的ViewDidLoad()代码:

      NSDictionary *xmlDict =  [[NSDictionary alloc]init];
    
       NSError *parseError = nil;
    
        xmlDict = [XMLReader dictionaryForXMLString:@"abc.xml"];  // which call's the XMLReader Class Method
    
       NSLog(@"MAIN CLASS OF Dictionary: %@",xmlDict);  // Gives the NULL Results.
    
  • 这是我的XMLReader.h代码

     #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;
    
              @end
    
    • 这是我的XMLReader.m代码

           #import "XMLReader.h"
      
              NSString *const kXMLReaderTextNodeKey = @"text";
      
                 @interface XMLReader (Internal)
      
               - (id)initWithError:(NSError **)error;
                - (NSDictionary *)objectWithData:(NSData *)data;
      
                  @end
      
                 @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;
                          }
                            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)
                         {
                              [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);
                         }
      
                @end
      

所以,在这段代码中,我用于将xml数据解析为字典格式。任何人都可以帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

尝试这样的事情。 Decalre在AppDelegate.h文件中的方法下面

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

在AppDelegate.m文件中添加方法定义

+(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]);
    }
    else{
        // 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:^{
            completionHandler(data);
        }];
    }
}];
}

现在从viewDtroller中调用此方法,如viewDidload

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

希望这会对你有所帮助