2011-02-25 47 views
11

我使用一个博客(http://troybrant.net/blog/)写了一个类,带有一个XML字符串,并吐出的NSDictionary。讨厌的新线和空白在XML阅读器类

它很漂亮......完美的作品,但我最终换行符的一个奇怪的配置和空格在许多元素值的开始。

我一直无法找出原因。我在这里张贴类,所以我可以得到一个第二双眼睛......看看有没有人注意到什么在他使用的方法嫌疑。

// 
// 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]; 
    [reader release]; 
    return rootDictionary; 
} 

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

#pragma mark - 
#pragma mark Parsing 

- (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) 
    { 
     [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 

如果这是一个恼人的问题,我很抱歉,(请不要投我失望出于赌气)。我只是想弄清楚这里发生了什么,缺乏编码能力来自己找到它。 (我是新来的OBJ-C)

克里夫

解决方案:

改变这一行:

[dictInProgress setObject:textInProgress forKey:kXMLReaderTextNodeKey]; 

这一行:

[dictInProgress setObject:[textInProgress stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] forKey:kXMLReaderTextNodeKey]; 
+0

你是金丹感谢很多 – 2015-08-04 11:42:04

回答

10

你可以修正您从该课程中获得的值:

NSString *trimmedValue = [value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 

这将删除前导空白和尾随空白。

+0

我一直在尝试类似的东西生命,但令人沮丧的是我将有一个这样的值:“\ n \ n \ n中的真棒价值”。所以我必须循环,直到我达到价值。很烦人。该字符集是否能够恰当地处理这种情况? (如果是这样,这是真棒......我一直在使用newLineCharacterSet..never注意到,一个) – clifgriffin 2011-02-25 16:38:49

+0

我觉得这个字符集应与在开始新的线条和空间任意组合应付。试试看:) – 2011-02-25 16:42:27

+0

你太棒了。这工作奇迹。谢谢。 – clifgriffin 2011-02-25 16:43:50