objective-c 如何使用 NSXMLParser 解析具有相同名称的父子元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2005448/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use NSXMLParser to parse parent-child elements that have the same name
提问by Hoang Pham
Does anyone have some idea how to parse the following xml using event-driven model NSXMLParser class?
有没有人知道如何使用事件驱动模型 NSXMLParser 类解析以下 xml?
<Node>
<name> Main </name>
<Node>
<name> Child 1 </name>
</Node>
<Node>
<name> Child 2 </name>
</Node>
</Node>
I want to collect all three names from this xml file, is it possible, or I have to change to Tree-based parsing?
我想从这个 xml 文件中收集所有三个名称,是否可能,或者我必须更改为基于树的解析?
回答by Adrian Kosmaczewski
This is a common problem with parsers like this one, of "type SAX", where you have to manually keep track of the current depth of the XML tree you're in. The problem, as always, is that loading the entire tree in a DOM structure in memory can be impossible, depending on the size of the data you want to manipulate.
这是像这样的“类型 SAX”解析器的一个常见问题,您必须手动跟踪您所在的 XML 树的当前深度。与往常一样,问题是加载整个树内存中的 DOM 结构可能是不可能的,这取决于您要操作的数据的大小。
The following code shows a class that does this job:
以下代码显示了一个完成这项工作的类:
#import <Foundation/Foundation.h>
@interface Test : NSObject <NSXMLParserDelegate>
{
@private
NSXMLParser *xmlParser;
NSInteger depth;
NSMutableString *currentName;
NSString *currentElement;
}
- (void)start;
@end
This is the implementation:
这是实现:
#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
This is the result of running a command line tool that triggers the "start" method above:
这是运行触发上述“start”方法的命令行工具的结果:
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
回答by yasirmturk
- (NSInteger)columnNumber
gives you the nesting level of NSXMLParser
为您提供嵌套级别 NSXMLParser
回答by brbgyn
A very easier way to solve it than the accepted answer, for short XML files:
对于简短的 XML 文件,比公认的答案更简单的解决方法:
XML example:
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>
Implement a counter:
实现一个计数器:
@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;
}
How will i know witch number is witch node ? By seeing the log. It will be something like:
我怎么知道女巫编号是女巫节点?通过查看日志。它会是这样的:
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:
The log will show you witch number is each node.
日志将显示每个节点的女巫编号。

