1

読みたいxmlに以下のアクションがあります。<goodactions>しかし、私はただ読んでみたいと思っています<niceactions>didStartElementデリゲート関数にフラグを配置する必要がありますか?

<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>
4

3 に答える 3

3

たぶんあなたは何か他のことを求めているかもしれませんが、単純なブール値で十分かもしれません。

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; 

    }

}
于 2012-04-26T19:49:27.607 に答える
1

はい、それは私がそれをする方法です。デリゲートの-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;
    }
}
于 2012-04-26T19:47:09.607 に答える
0

特定のノードまたはブランチを無視する最も簡単な解決策は、独自の 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
于 2014-12-28T14:32:09.433 に答える