如何使用NSXMLParser来parsing具有相同名称的父子元素

有没有人有一些想法如何使用事件驱动的模型NSXMLParser类来parsing下面的XML?

<Node> <name> Main </name> <Node> <name> Child 1 </name> </Node> <Node> <name> Child 2 </name> </Node> </Node> 

我想从这个XML文件收集所有三个名字,这是可能的,或者我必须改变为基于树的parsing?

这是像这样的parsing器的一个常见问题,types为“SAX”,您必须手动跟踪您所在的XML树的当前深度。问题与往常一样,是将整个树加载到内存中的DOM结构可能是不可能的,这取决于您要处理的数据的大小。

以下代码显示了执行此作业的类:

 #import <Foundation/Foundation.h> @interface Test : NSObject <NSXMLParserDelegate> { @private NSXMLParser *xmlParser; NSInteger depth; NSMutableString *currentName; NSString *currentElement; } - (void)start; @end 

这是执行:

 #import "Test.h" @interface Test () - (void)showCurrentDepth; @end @implementation Test - (void)dealloc { [currentElement release]; [currentName release]; [xmlParser release]; [super dealloc]; } - (void)start { NSString *xml = @"<?xml version=\"1.0\" encoding=\"UTF-8\" ?><Node><name>Main</name><Node><name>Child 1</name></Node><Node><name>Child 2</name></Node></Node>"; xmlParser = [[NSXMLParser alloc] initWithData:[xml dataUsingEncoding:NSUTF8StringEncoding]]; [xmlParser setDelegate:self]; [xmlParser setShouldProcessNamespaces:NO]; [xmlParser setShouldReportNamespacePrefixes:NO]; [xmlParser setShouldResolveExternalEntities:NO]; [xmlParser parse]; } #pragma mark - #pragma mark NSXMLParserDelegate methods - (void)parserDidStartDocument:(NSXMLParser *)parser { NSLog(@"Document started", nil); depth = 0; currentElement = nil; } - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError { NSLog(@"Error: %@", [parseError localizedDescription]); } - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { [currentElement release]; currentElement = [elementName copy]; if ([currentElement isEqualToString:@"Node"]) { ++depth; [self showCurrentDepth]; } else if ([currentElement isEqualToString:@"name"]) { [currentName release]; currentName = [[NSMutableString alloc] init]; } } - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { if ([elementName isEqualToString:@"Node"]) { --depth; [self showCurrentDepth]; } else if ([elementName isEqualToString:@"name"]) { if (depth == 1) { NSLog(@"Outer name tag: %@", currentName); } else { NSLog(@"Inner name tag: %@", currentName); } } } - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { if ([currentElement isEqualToString:@"name"]) { [currentName appendString:string]; } } - (void)parserDidEndDocument:(NSXMLParser *)parser { NSLog(@"Document finished", nil); } #pragma mark - #pragma mark Private methods - (void)showCurrentDepth { NSLog(@"Current depth: %d", depth); } @end 

这是运行一个触发上面的“开始”方法的命令行工具的结果:

 Document started Current depth: 1 Outer name tag: Main Current depth: 2 Inner name tag: Child 1 Current depth: 1 Current depth: 2 Inner name tag: Child 2 Current depth: 1 Current depth: 0 Document finished 
 - (NSInteger)columnNumber 

为您提供NSXMLParser的嵌套级别

对于简短的XML文件来说,解决这个问题的方法比接受的答案要简单得多:

XML示例:

 <cotacoes> <bovespa> <cotacao>50058</cotacao> <variacao>-0.16</variacao> </bovespa> <dolar> <cotacao>3.4610</cotacao> <variacao>+0.29</variacao> </dolar> <euro> <cotacao>3.7673</cotacao> <variacao>-0.25</variacao> </euro> <atualizacao>04/08/15 - 18:14</atualizacao> </cotacoes> 

实施一个计数器:

 @implementation className{ int parserCounter; } - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { parserCounter++; NSLog(@"%d: %@",contadorParser,string); if (parserCounter == 3) doAnythingFor3; if (parserCounter == 5) doAnythingFor5; if (parserCounter == 9) doAnythingFor9; if (parserCounter == 11) doAnythingFor11; if (parserCounter == 15) doAnythingFor15; if (parserCounter == 17) doAnythingFor17; if (parserCounter == 20) doAnythingFor20; } 

我怎么知道女巫号码是女巫节点? 通过看日志。 它会是这样的:

 2015-08-04 23:36:08.070 Tesouro Direto[7252:1554402] 1: 2015-08-04 23:36:08.070 Tesouro Direto[7252:1554402] 2: 2015-08-04 23:36:08.071 Tesouro Direto[7252:1554402] 3: 50058 2015-08-04 23:36:08.105 Tesouro Direto[7252:1554402] 4: 2015-08-04 23:36:08.105 Tesouro Direto[7252:1554402] 5: -0.16 2015-08-04 23:36:08.131 Tesouro Direto[7252:1554402] 6: 2015-08-04 23:36:08.132 Tesouro Direto[7252:1554402] 7: 2015-08-04 23:36:08.132 Tesouro Direto[7252:1554402] 8: 2015-08-04 23:36:08.132 Tesouro Direto[7252:1554402] 9: 3.4610 2015-08-04 23:36:08.156 Tesouro Direto[7252:1554402] 10: 2015-08-04 23:36:08.156 Tesouro Direto[7252:1554402] 11: +0.29 2015-08-04 23:36:08.180 Tesouro Direto[7252:1554402] 12: 2015-08-04 23:36:08.180 Tesouro Direto[7252:1554402] 13: 2015-08-04 23:36:08.180 Tesouro Direto[7252:1554402] 14: 2015-08-04 23:36:08.180 Tesouro Direto[7252:1554402] 15: 3.7673 2015-08-04 23:36:08.203 Tesouro Direto[7252:1554402] 16: 2015-08-04 23:36:08.203 Tesouro Direto[7252:1554402] 17: -0.25 2015-08-04 23:36:08.226 Tesouro Direto[7252:1554402] 18: 2015-08-04 23:36:08.227 Tesouro Direto[7252:1554402] 19: 2015-08-04 23:36:08.227 Tesouro Direto[7252:1554402] 20: 04/08/15 - 18:14 2015-08-04 23:36:08.227 Tesouro Direto[7252:1554402] 21: 

日志会显示你的女巫号码是每个节点。