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

Hoa*_*ham 8 iphone objective-c nsxmlparser xml-parsing

有没有人知道如何使用事件驱动的模型NSXMLParser类解析以下xml?

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

  <Node>
    <name> Child 2 </name>
  </Node>
</Node>
Run Code Online (Sandbox Code Playgroud)

我想从这个xml文件中收集所有三个名字,是否可能,或者我必须更改为基于树的解析?

Adr*_*ski 32

这是像"SAX类型"这样的解析器的常见问题,你必须手动跟踪你所在的XML树的当前深度.问题一如既往地是将整个树加载到内存中的DOM结构是不可能的,具体取决于您要操作的数据的大小.

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

#import <Foundation/Foundation.h>

@interface Test : NSObject <NSXMLParserDelegate> 
{
@private
    NSXMLParser *xmlParser;
    NSInteger depth;
    NSMutableString *currentName;
    NSString *currentElement;
}

- (void)start;

@end
Run Code Online (Sandbox Code Playgroud)

这是实施:

#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
Run Code Online (Sandbox Code Playgroud)

这是运行命令行工具的结果,该工具触发上面的"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
Run Code Online (Sandbox Code Playgroud)


yas*_*urk 6

- (NSInteger)columnNumber
Run Code Online (Sandbox Code Playgroud)

给你嵌套级别 NSXMLParser