0

NSXMLParserを初めて使用し、次のようなhttpリクエストから返されたxmlを解析する方向を教えてください。

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

デリゲートメソッドの解析の基本を知っていますが、上記のアイテム(通貨/アイテム/配送/税金)を取得するためのdidEndElement / foundCharacters / didStartElementのコードがどのようになるかを知りたいだけですか?どんな助けでも大歓迎です。

4

2 に答える 2

1

NSXMLParserこれは、いくつかの標準コードよりも少し注意が必要です。shipping基本的に「必要な」を探しているときですが6.00、これら2つのデータは異なるデリゲートメソッドで返されますが、これは正常なことです。ただし、通常、要素には「shipping」という名前が付けられるためparser:didEndElement:namespaceURI:qualifiedName:、メソッドに渡されたときに自動的に要素名が付けられます。

解決策は単純に見え、_currentAttributesivarがあり、次のparser:didStartElement:namespaceURI:qualifiedName:attributes:ようなことをしてから、メソッド_currentAttributes = attributeDict;でこれを処理します。didEndElement:ただし、この適度に単純な場合でも、このスタイルは簡単に損益分岐点になりXMLます。

これを処理する私の方法は、に渡された属性ディクショナリを格納しdidStartElement:、要素名のキーのオブジェクトとしてディクショナリに設定することです。このスタイルを、ある種のcharacterBufferとしての標準的な使用法と組み合わせると、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";
}
于 2012-04-08T18:55:19.370 に答える
0

このチュートリアルをチェックしてください。NSXMLParserを使用して、XMLから独自のデータ形式にデータを解析する方法について説明します。

于 2012-04-06T19:02:24.693 に答える