2011-02-25 16 views
11

Estoy usando una clase escrita por un blogger (http://troybrant.net/blog/) que toma una cadena XML y escupe un NSDictionary.Nuevas y molestas líneas y espacios en blanco en la clase de lector XML

Es hermoso ... funciona a la perfección, excepto que termino con una extraña configuración de saltos y espacios en blanco al comienzo de muchos valores de elementos.

No he podido averiguar por qué. Estoy publicando la clase aquí para que pueda obtener un segundo par de ojos ... ver si alguien nota algo sospechoso en el método que está usando.

// 
// 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 

Si se trata de una cuestión molesta, me disculpo (y por favor no me voten abajo por despecho). Solo estoy tratando de descubrir qué está pasando aquí y la falta de destreza en la codificación para encontrarlo yo mismo. (Soy nuevo en Obj-C)

Clif

Solución:

cambiar esta línea:

[dictInProgress setObject:textInProgress forKey:kXMLReaderTextNodeKey]; 

Para esta línea:

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

eres un salvavidas gracias mucho –

Respuesta

10

Usted podría recortar los valores que obtiene de esa clase:

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

Eso eliminaría el espacio en blanco inicial y final.

+0

He estado intentando algo así, pero la parte frustrante es que voy a tener un valor como este: "\ n \ n \ n The Awesome Value". Así que tengo que seguir hasta alcanzar el valor. Muy molesto. ¿Ese conjunto de caracteres manejará adecuadamente este escenario? (Si es así, eso es IMPRESIONANTE ... He estado usando newLineCharacterSet ... nunca lo he notado) – clifgriffin

+0

Creo que este conjunto de caracteres debe hacer frente a cualquier combinación de nuevas líneas y espacios al inicio. Pruébalo :) –

+0

Eres increíble. Esto funcionó de maravillas. Gracias. – clifgriffin

Cuestiones relacionadas