これは、明確に定義された繰り返し要素 (この場合は"trip"
) の基本モデルと、その中の一連のデータ要素に従う XML ファイルから辞書を作成するためによく使用するコードです。タグの属性 (この場合は"takeoff"
,"landing"
と"flight"
)、その他 開始タグと終了タグの間のデータ (この場合は のみ) を読み取ります"price"
。
私は次のivarを持っています:
@interface XmlParserViewController () <NSXMLParserDelegate>
{
NSMutableArray *trips;
NSMutableDictionary *currentTrip;
NSMutableString *currentElement;
}
@end
コードは次のようになります。
- (void)viewDidLoad
{
[super viewDidLoad];
trips = [[NSMutableArray alloc] init];
// I'm getting my xml from my bundle. You get it however you're currently getting it.
NSString *filename = [[NSBundle mainBundle] pathForResource:@"results" ofType:@"xml"];
NSData *data = [NSData dataWithContentsOfFile:filename];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
parser.delegate = self;
[parser parse];
}
#pragma mark - NSXMLParserDelegate methods
#define kRowElementTag @"trip"
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
NSArray *attributeElementNames = @[@"takeoff", @"landing", @"flight"];
NSArray *foundCharacterElementNames = @[@"price"];
if ([elementName isEqualToString:kRowElementTag])
{
currentTrip = [[NSMutableDictionary alloc] init];
[trips addObject:currentTrip];
if (attributeDict)
[currentTrip setObject:attributeDict forKey:elementName];
}
else if (currentTrip)
{
if ([attributeElementNames containsObject:elementName])
{
if (attributeDict)
[currentTrip setObject:attributeDict forKey:elementName];
}
else if ([foundCharacterElementNames containsObject:elementName] && currentElement == nil)
{
// you can change this to just grab a few fields ... add whatever fields you want to this
currentElement = [[NSMutableString alloc] init];
[currentTrip setObject:currentElement forKey:elementName];
}
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:kRowElementTag])
{
currentTrip = nil;
}
else if (currentElement)
{
currentElement = nil;
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (currentElement)
{
[currentElement appendString:string];
}
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
NSLog(@"%s error=%@", __FUNCTION__, parseError);
// we should handle the error here
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
NSLog(@"%s trips=%@", __FUNCTION__, trips);
// generally I immediately kick off the reload of the table, but maybe
// you want to grok the trips dictionary first.
//
// [self.tableView reloadData];
}
ご想像のとおり、JSON ファイルの解析に慣れてきた、入れ子になった配列/辞書構造のようなものに終わろうとしています。明らかに、XML ファイルの構造の一部をコードで前もって特定しなければならないという事実 (外側の配列には、 、、および"trip"
というタグがありますが、"price"` には属性がないという事実) が好きではありません。 t) など。しかし、これは、あちこちにハードコーディングされた値を XML 解析で最初に試みた場合よりも少し優れています。はぁ。"takeoff"
"landing"
"flight"