仮定 1. p (段落) 要素のデータのみに関心があり、NSXMLParser を使用しているとします。
仮定 2. p 内のすべての要素をそのまま保持したい。
使用したい戦略は、パーサーのステート マシンを作成して、いつデータを保存する必要があるか、いつ受信したデータを無視するかを認識できるようにすることです。
NSXMLParser delegateApple のサンプル コードを使用してセットアップします。BOOL inParagraphデリゲートには、データが保持または破棄されるタイミングを追跡するための ivar が必要です。の初期値はinParagaphですNO。デリゲートがparser:didStartElement:namespaceURI:qualifiedName:attributes:メッセージを受信したら、変数をif ([element isEqual:@"p"])クリアして設定しますreceivedDatainParagraph = YES
編集: receivedData は NSMutableString です。コード例を修正
この時点で、parser delegate受信したデータを保存したいと考えています。
parser delegateがメッセージを受信したら、サンプル コードのようにparser:foundCharacters:文字列を に追加します。receivedData
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (inParagraph) [receivedData appendString:string];
}
パーサーがインライン要素に遭遇すると、デリゲートは再び受け取りますparser:didStartElement:namespaceURI:qualifiedName:attributes:。これは、inParagraph状態変数が重要な場合です。パーサーは要素を囲む '<' と '>' 文字を受け取りませelementNameんreceivedData。何かのようなもの
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{ if (inParagraph)
{
NSString *inlineElementName = [NSString stringWithFormat:@"<%@>", elementName];
[receivedData appendString:inlineElementName];
}
....
}
はメッセージparser delegateを受信するparser:didEndElement:namespaceURI:qualifiedName:と、それが "p" 要素内にあるかどうかをチェックしif (inParagraph && ![elementName isEqual:@"p"]、インライン要素を閉じます。のコンテンツを保持する段落if ([elementName isEqual:@"p"])に追加します。receivedDataNSMutableArray
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if (inParagraph)
{
if (![elementName isEqual:@"p"])
{
NSString *inlineElementName = [NSString stringWithFormat:@"</%@>", elementName];
[receivedData appendString:inlineElementName];
} else { // received closing </p> tag add receivedData to the paragraph array
[paragraphsArray addObject:[receivedData copy]];
[self setInParagraph:NO];
}
}
}
}