2012-04-05 7 views
0

Es ist erstmals NSXMLParser mit und frage mich, ob Sie mir geben eine Richtung von den zurückgegebenen XML-Daten aus einer HTTP-Anforderung Parsen, die wie folgt aussieht:iOS: Parsen eine xml von HTTP NSXMLParser für

<?xml version="1.0" ?> 
<theresponse> 
<status>OK</status> 
<pricing currency="USD" symbol="$"> 
    <price class="items">24.00</price> 
    <price class="shipping">6.00</price> 
    <price class="tax">1.57</price> 
</pricing> 
</theresponse> 

ich die Grund kennen Ich möchte nur wissen, wie der Code in didEndElement/foundCharacters/didStartElement aussehen würde, um die oben genannten Elemente (Währung/Artikel/Versand/Steuern) zu reaktivieren? jede Hilfe sehr geschätzt.

Antwort

1

Dies ist ein wenig komplizierter als einige Standard NSXMLParser Code; Denn im Wesentlichen, wenn Sie nach der "shipping" suchen, möchten Sie "6.00", aber diese beiden Daten werden Ihnen in verschiedenen Delegate-Methoden zurückgegeben, was normal ist. Aber normalerweise würde das Element "shipping" heißen, so dass Sie in parser:didEndElement:namespaceURI:qualifiedName: automatisch den Elementnamen haben würden, wie er an die Methode übergeben wurde.

Die Lösung wäre einfach erscheinen, haben eine _currentAttributes Ivar und in parser:didStartElement:namespaceURI:qualifiedName:attributes: wie _currentAttributes = attributeDict; etwas zu tun, und diese dann in der didEndElement: Methode zu behandeln. Allerdings würde dieser Stil leicht brechen, selbst auf diesem mäßig einfachen XML.

Meine Art, dies zu handhaben, wäre, das Attributverzeichnis zu speichern, das an die didStartElement: übergeben wurde, und es in einem Wörterbuch als Objekt für den Schlüssel des Elementnamens festzulegen. Kombinieren Sie diesen Stil mit der Standard-Verwendung eines NSMutableString als characterBuffer von Arten können Sie alle Ihre Logik in die didEndElement:-Methode setzen.

Seitennotiz: Ich bin auch ziemlich gerne meine NSXMLParserDelegate Klassen NSXMLParser Unterklassen, wie dieser ist. Die Delegiertenmethoden wären jedoch identisch, wenn dies nicht der Fall wäre.

ItemParser.h

#import <Foundation/Foundation.h> 
@interface ItemParser : NSXMLParser <NSXMLParserDelegate> 
@property (readonly) NSDictionary *itemData; 
@end 

ItemParser.m

#import "ItemParser.h" 
@implementation ItemParser { 
    NSMutableDictionary *_itemData; 
    NSMutableDictionary *_attributesByElement; 
    NSMutableString *_elementString; 
} 
-(NSDictionary *)itemData{ 
    return [_itemData copy]; 
} 
-(void)parserDidStartDocument:(NSXMLParser *)parser{ 
    _itemData = [[NSMutableDictionary alloc] init]; 
    _attributesByElement = [[NSMutableDictionary alloc] init]; 
    _elementString = [[NSMutableString alloc] init]; 
} 
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{ 
    // Save the attributes for later. 
    if (attributeDict) [_attributesByElement setObject:attributeDict forKey:elementName]; 
    // Make sure the elementString is blank and ready to find characters 
    [_elementString setString:@""]; 
} 
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{ 
    // Save foundCharacters for later 
    [_elementString appendString:string]; 
} 
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{ 
    if ([elementName isEqualToString:@"status"]){ 
     // Element status only contains a string i.e. "OK" 
     // Simply set a copy of the element value string in the itemData dictionary 
     [_itemData setObject:[_elementString copy] forKey:elementName]; 
    } else if ([elementName isEqualToString:@"pricing"]) { 
     // Pricing has an interesting attributes dictionary 
     // So copy the entries to the item data 
     NSDictionary *attributes = [_attributesByElement objectForKey:@"pricing"]; 
     [_itemData addEntriesFromDictionary:attributes]; 
    } else if ([elementName isEqualToString:@"price"]) { 
     // The element price occurs multiple times. 
     // The meaningful designation occurs in the "class" attribute. 
     NSString *class = [[_attributesByElement objectForKey:elementName] objectForKey:@"class"]; 
     if (class) [_itemData setObject:[_elementString copy] forKey:class]; 
    } 
    [_attributesByElement removeObjectForKey:elementName]; 
    [_elementString setString:@""]; 
} 
-(void)parserDidEndDocument:(NSXMLParser *)parser{ 
    _attributesByElement = nil; 
    _elementString = nil; 
} 
-(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{ 
    NSLog(@"%@ with error %@",NSStringFromSelector(_cmd),parseError.localizedDescription); 
} 
-(BOOL)parse{ 
    self.delegate = self; 
    return [super parse]; 
} 
@end 

Und so testen ich die gespeicherte XML Sie oben in eine dem Namen "ItemXML.xml" Datei geschrieben. Und es getestet mit diesem Code:

NSURL *url = [[NSBundle mainBundle] URLForResource:@"ItemXML" withExtension:@"xml"]; 
ItemParser *parser = [[ItemParser alloc] initWithContentsOfURL:url]; 
[parser parse]; 
NSLog(@"%@",parser.itemData); 

Das Ergebnis, das ich bekam, war:

{ 
    currency = USD; 
    items = "24.00"; 
    shipping = "6.00"; 
    status = OK; 
    symbol = "$"; 
    tax = "1.57"; 
} 
+0

Thank you so much. – Cam

0

Überprüfen Sie diese tutorial. Es wird erläutert, wie Sie den NSXMLParser verwenden, um Daten aus XML in Ihr eigenes Datenformat zu analysieren.

Verwandte Themen