這比一些標準的NSXMLParser
代碼稍微棘手;因爲基本上當你在尋找「shipping
」時,你想要「6.00
」,但這兩部分數據以不同的委託方法返回給你,這是正常的。但通常該元素將被命名爲「shipping
」,因此在parser:didEndElement:namespaceURI:qualifiedName:
中,您將自動獲得元素名稱,因爲它已傳入方法中。
的解決辦法似乎很簡單,有一個_currentAttributes
伊娃和parser:didStartElement:namespaceURI:qualifiedName:attributes:
這樣做_currentAttributes = attributeDict;
然後在didEndElement:
方法處理這個問題。然而,這種風格很容易破碎,即使在這個適度簡單的XML
。
我的處理方法是存儲傳遞到didStartElement:
的屬性字典,並將其設置在字典中作爲元素名稱的鍵的對象。將這種風格與NSMutableString
作爲字符緩衝區的標準用法結合使用,可以將所有邏輯放入didEndElement:
方法中。
附註:我也很喜歡讓我的NSXMLParserDelegate
類是NSXMLParser
的子類,就像這個。然而,如果委託方法不是,委託方法將是相同的。
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
所以測試我存儲在XML
你上面貼到一個名爲 「ItemXML.xml」 文件。
NSURL *url = [[NSBundle mainBundle] URLForResource:@"ItemXML" withExtension:@"xml"];
ItemParser *parser = [[ItemParser alloc] initWithContentsOfURL:url];
[parser parse];
NSLog(@"%@",parser.itemData);
我得到的結果是:
{
currency = USD;
items = "24.00";
shipping = "6.00";
status = OK;
symbol = "$";
tax = "1.57";
}
謝謝你這麼多,使用此代碼進行了測試。 – Cam 2012-04-09 19:28:00