2012年2月23日木曜日

SOAP レスポンスのパース



iOSにはDOMのパーサーは含まれていないため、SAXパーサーのNSXMLParserでSOAPレスポンスのXMLをパースします。
処理の手順は概ね次のようになります。

//インスタンス変数
NSMutableString *soapResults;
NSDictionary *attributes;
BOOL elementFound;

//dataをパースしsoapResultsに結果をセットする。
- (void)someMethod:(NSData *)data
{
    //受信したデータ(NSData)を渡してNSXMLParserを作る。
    NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:data];

    //delegateセット
    [xmlParser setDelegate:self];

    //パース開始。パース中にNSXMLParserDelegateメソッドが呼ばれる。
    soapResults = [[NSMutableString alloc] init];
    [xmlParser parse];
}

#pragma mark - NSXMLParserDelegate

//要素タグの開始
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
                                        namespaceURI:(NSString *)namespaceURI
                                       qualifiedName:(NSString *)qName
                                          attributes:(NSDictionary *)attributeDict
{
    //Resultタグが見つかったらフラグをセット
    if ([elementName hasSuffix:@"Result"]) {
        elementFound = YES;
        //属性のセット
        attributes = [NSDictionary dictionaryWithDictionary:attributeDict ];
    }
}

//タグのtextノードの値が渡される。複数回呼ばれることがある。
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    if (elementFound)
    {
        [soapResults appendString:string];
    }
}

//タグ終了時に呼ばれる。
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
                                     namespaceURI:(NSString *)namespaceURI
                                    qualifiedName:(NSString *)qName
{
    elementFound = NO;
}

私はサーバーでXMLを作り文字列で返すようにしましたが、この場合はResultにそのXMLが入っているため、再度上記の要領でパースします。

SOAPレスポンスのResultタグにはattributeはありませんが、このXMLにはattributeがあり 、didStartElementのattributeDictにセットされて渡されてきます。

関連Blog

iOS アプリからのSOAP/WebServiceへのアクセス
SOAP レスポンスの受信
SOAP レスポンスのパース
バイナリデータのSOAPレスポンス
SOAPリクエスト/レスポンスとの同期


<参照>
Consuming XML Web Services in iPhone Applications
iPhoneアプリケーションでXML Webサービスを利用する

0 件のコメント: