Objective c NSXMLParser忽略节点

Objective c NSXMLParser忽略节点,objective-c,ios,nsxmlparser,Objective C,Ios,Nsxmlparser,我想阅读以下xml中的操作。但是我只想读和。我是否需要在didStartElementdelegate函数中放置标志 <goodactions> <action name=\"play\" id=\"0\"/> <action name=\"eat\" id=\"1\" /> <action name=\"sleep\" id=\"2\" /> <action name=\"study\" id=\"3\"/> <

我想阅读以下xml中的操作。但是我只想读
。我是否需要在
didStartElement
delegate函数中放置标志

<goodactions>
  <action name=\"play\" id=\"0\"/>
  <action name=\"eat\" id=\"1\" />
  <action name=\"sleep\" id=\"2\" />
  <action name=\"study\" id=\"3\"/>
</goodactions>
<badactions>
  <action name=\"smoke\" id=\"0\"/>
  <action name=\"watch_tv\" id=\"1\"/>
</badactions>
<niceactions>
  <action name=\"cycling\" id=\"0\"/>
  <action name=\"swimming\" id=\"1\"/>
</niceactions>

是的,我就是这么做的。调用委托的
-parser:didStartElement::
方法时,如果元素名为“badactions”,则设置一个标志以忽略所有内容。然后在
-parser:didEndElement:
中,如果元素名为“badactions”,则重置标志。大概是这样的:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    if ([elementName isEqualToString:@"badactions"])
    {
        _ignoreElement = YES;
        return;
    }
    if (!_ignoreElement)
    {
         // handle other elements here
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    // Reset if we were ignoring a badactions element
    if (([elementName isEqualToString:@"badactions"]) && (_ignoreElement))
    {
         _ignoreElement = NO;
    }
}

是的,我就是这样做的。调用委托的
-parser:didStartElement::
方法时,如果元素名为“badactions”,则设置一个标志以忽略所有内容。然后在
-parser:didEndElement:
中,如果元素名为“badactions”,则重置标志。大概是这样的:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    if ([elementName isEqualToString:@"badactions"])
    {
        _ignoreElement = YES;
        return;
    }
    if (!_ignoreElement)
    {
         // handle other elements here
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    // Reset if we were ignoring a badactions element
    if (([elementName isEqualToString:@"badactions"]) && (_ignoreElement))
    {
         _ignoreElement = NO;
    }
}

也许你在问别的问题,但是一个简单的布尔值就足够了

BOOL ignoreElement; 

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {

    if ([elementName isEqualToString:@"badactions"]) {

        self.ignoreElement = YES; 

    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {

    if (!self.ignoreElement) {
        // data from other elements
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

    if ([elementName isEqualToString:@"badactions"]) {

        self.ignoreElement = NO; 

    }

}

也许你在问别的问题,但是一个简单的布尔值就足够了

BOOL ignoreElement; 

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {

    if ([elementName isEqualToString:@"badactions"]) {

        self.ignoreElement = YES; 

    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {

    if (!self.ignoreElement) {
        // data from other elements
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

    if ([elementName isEqualToString:@"badactions"]) {

        self.ignoreElement = NO; 

    }

}

忽略特定节点或分支的最简单解决方案是创建自己的类似XPath的XML路径并维护元素堆栈

所以,每当解析新元素时,都会将节点推到堆栈上,并更新当前XML路径。然后,当您偶然发现结束标记时,只需从堆栈中弹出元素

然而,您的堆栈可能不一致,因为您可能希望忽略一些分支,所以您可以始终保留关闭标记的XMLPath和堆栈上的最后一个节点,并与之进行比较

在下面的示例中,我使用点分隔符存储XML路径。它既便宜又容易解析和比较

作为该方法的一个优点,您可以实现一些简单的比较算法,忽略或匹配XML结构中间的特定分支,但深入和解析特定节点。 拥有一堆元素是一个巨大的好处,因为如果您需要用位于层次结构深处的一些信息填充相关节点,您总是可以引用它们

// Base node class
@interface MYNode : NSObject

@property NSString* XMLPath;

@end

// Some custom node subclass
@interface MYRootNode : MYNode @end

// Some other custom node subclass
@interface MYBlockNode : MYNode @end

// NSXMLParserDelegate interface
@interface MYXMLParserDelegate : NSObject<NSXMLParserDelegate>

@property NSMutableArray* elementStack;
@property NSString* XMLPath;
@property MYRootNode* rootNode;

@end

// NSXMLParserDelegate implementation
@implementation MYXMLParserDelegate

#pragma mark - Initializer

- (id)init {
    if(self = [super init]) {
        self.elementStack = [NSMutableArray new];
    }
    return self;
}

#pragma mark - XMLPath manipulation methods

- (void)addXMLPathComponent:(NSString*)component {
    NSString* newXMLPath;

    if(self.XMLPath.length) {
        newXMLPath = [self.XMLPath stringByAppendingFormat:@".%@", component];
    } else {
        newXMLPath = component;
    }

    self.XMLPath = newXMLPath;
}

- (void)removeLastXMLPathComponent {
    NSRange range = [self.XMLPath rangeOfString:@"." options:NSBackwardsSearch];
    if(range.location != NSNotFound) {
        self.XMLPath = [self.XMLPath substringToIndex:range.location];
    }
}

#pragma mark - NSXMLParserDelegate

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    MYNode* node;

    // Add XML path component
    [self addXMLPathComponent:elementName];

    // Process relevant nodes
    if([self.XMLPath isEqualToString:@"document.page"])
    {
        node = [[MYRootNode alloc] initWithAttributes:attributeDict];

        // Save root node
        self.rootNode = node;
    }
    else if([self.XMLPath isEqualToString:@"document.page.block"])
    {
        node = [[MYBlockNode alloc] initWithAttributes:attributeDict];
    }

    // Push relevant node on stack
    if(node) {
        node.XMLPath = self.XMLPath;
        [self.elementStack addObject:node];

        NSLog(@"-> %@", self.XMLPath);
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    MYNode* node = [self.elementStack lastObject];

    // Remove node from stack if XML path match found    
    if([node.XMLPath isEqualToString:self.XMLPath]) {
        [self.elementStack removeLastObject];

        NSLog(@"<- %@", self.XMLPath);
    }

    // Pop XML path component
    [self removeLastXMLPathComponent];
}

@end
//基本节点类
@接口MYNode:NSObject
@属性NSString*XMLPath;
@结束
//一些自定义节点子类
@接口MYRootNode:MYNode@end
//其他一些自定义节点子类
@接口MYBlockNode:MYNode@end
//NSXMLParserDelegate接口
@接口MYXMLParserDelegate:NSObject
@属性NSMutableArray*elementStack;
@属性NSString*XMLPath;
@属性MYRootNode*rootNode;
@结束
//NSXMLParserDelegate实现
@实现MYXMLParserDelegate
#pragma标记初始值设定项
-(id)init{
if(self=[super init]){
self.elementStack=[NSMutableArray new];
}
回归自我;
}
#pragma标记-XMLPath操作方法
-(void)addXMLPathComponent:(NSString*)组件{
NSString*newXMLPath;
if(self.XMLPath.length){
newXMLPath=[self.XMLPath stringByAppendingFormat:@“%@”,component];
}否则{
newXMLPath=组件;
}
self.XMLPath=newXMLPath;
}
-(void)removeLastXMLPathComponent{
NSRange range=[self.XMLPath rangeOfString:@.”选项:nsbackardssearch];
if(range.location!=NSNotFound){
self.XMLPath=[self.XMLPath substringToIndex:range.location];
}
}
#pragma标记-NSXMLParserDelegate
-(void)parser:(NSXMLParser*)parser didStartElement:(NSString*)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString*)qName属性:(NSDictionary*)attributeDict{
MYNode*node;
//添加XML路径组件
[self-addXMLPathComponent:elementName];
//处理相关节点
if([self.XMLPath isEqualToString:@“document.page”])
{
node=[[MYRootNode alloc]initWithAttributes:attributeDict];
//保存根节点
self.rootNode=节点;
}
else if([self.XMLPath IsequalString:@“document.page.block”])
{
node=[[MYBlockNode alloc]initWithAttributes:attributeDict];
}
//将相关节点推送到堆栈上
如果(节点){
node.XMLPath=self.XMLPath;
[self.elementStack addObject:node];
NSLog(@->%@),self.XMLPath;
}
}
-(void)parser:(NSXMLParser*)parser didEndElement:(NSString*)elementName namespaceURI:(NSString*)namespaceURI qualifiedName:(NSString*)qName{
MYNode*node=[self.elementStack lastObject];
//如果发现XML路径匹配,则从堆栈中删除节点
if([node.XMLPath isEqualToString:self.XMLPath]){
[self.element堆栈移除对象];

NSLog(@“忽略特定节点或分支的最简单解决方案是创建自己的类似XPath的XML路径并维护元素堆栈

所以,每当你们解析新元素时,你们就把节点推到堆栈上,并更新当前的XML路径。然后当你们偶然发现关闭标记时,你们就从堆栈中弹出元素

然而,您的堆栈可能不一致,因为您可能希望忽略一些分支,所以您可以始终保留关闭标记的XMLPath和堆栈上的最后一个节点,并与之进行比较

在下面的示例中,我使用点分隔符存储XML路径。它既便宜又易于解析和比较

作为该方法的一个优点,您可以实现一些简单的比较算法,忽略或匹配XML结构中间的特定分支,但深入和解析特定节点。 拥有一堆元素是一个巨大的好处,因为如果您需要用位于层次结构深处的一些信息填充相关节点,您总是可以引用它们

// Base node class
@interface MYNode : NSObject

@property NSString* XMLPath;

@end

// Some custom node subclass
@interface MYRootNode : MYNode @end

// Some other custom node subclass
@interface MYBlockNode : MYNode @end

// NSXMLParserDelegate interface
@interface MYXMLParserDelegate : NSObject<NSXMLParserDelegate>

@property NSMutableArray* elementStack;
@property NSString* XMLPath;
@property MYRootNode* rootNode;

@end

// NSXMLParserDelegate implementation
@implementation MYXMLParserDelegate

#pragma mark - Initializer

- (id)init {
    if(self = [super init]) {
        self.elementStack = [NSMutableArray new];
    }
    return self;
}

#pragma mark - XMLPath manipulation methods

- (void)addXMLPathComponent:(NSString*)component {
    NSString* newXMLPath;

    if(self.XMLPath.length) {
        newXMLPath = [self.XMLPath stringByAppendingFormat:@".%@", component];
    } else {
        newXMLPath = component;
    }

    self.XMLPath = newXMLPath;
}

- (void)removeLastXMLPathComponent {
    NSRange range = [self.XMLPath rangeOfString:@"." options:NSBackwardsSearch];
    if(range.location != NSNotFound) {
        self.XMLPath = [self.XMLPath substringToIndex:range.location];
    }
}

#pragma mark - NSXMLParserDelegate

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    MYNode* node;

    // Add XML path component
    [self addXMLPathComponent:elementName];

    // Process relevant nodes
    if([self.XMLPath isEqualToString:@"document.page"])
    {
        node = [[MYRootNode alloc] initWithAttributes:attributeDict];

        // Save root node
        self.rootNode = node;
    }
    else if([self.XMLPath isEqualToString:@"document.page.block"])
    {
        node = [[MYBlockNode alloc] initWithAttributes:attributeDict];
    }

    // Push relevant node on stack
    if(node) {
        node.XMLPath = self.XMLPath;
        [self.elementStack addObject:node];

        NSLog(@"-> %@", self.XMLPath);
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    MYNode* node = [self.elementStack lastObject];

    // Remove node from stack if XML path match found    
    if([node.XMLPath isEqualToString:self.XMLPath]) {
        [self.elementStack removeLastObject];

        NSLog(@"<- %@", self.XMLPath);
    }

    // Pop XML path component
    [self removeLastXMLPathComponent];
}

@end
//基本节点类
@接口MYNode:NSObject
@属性NSString*XMLPath;
@结束
//一些自定义节点子类
@接口MYRootNode:MYNode@end
//其他一些自定义节点子类
@接口MYBlockNode:MYNode@end
//NSXMLParserDelegate接口
@接口MYXMLParserDelegate:NSObject
@属性NSMutableArray*elementStack;
@属性NSString*XMLPath;
@属性MYRootNode*rootNode;
@结束
//NSXMLParserDelegate实现
@实现MYXMLParserDelegate
#pragma标记初始值设定项
-(id)init{
if(self=[super init]){
self.elementStack=[NSMutableAr