NSXMLParser不解析某些内容

LaK*_*LaK -1 cocoa-touch objective-c nsxmlparser

我的iOS应用程序解析从远程服务器获取的xml(我不能以任何方式影响).当它遇到如下所示的xml标记时:

<tag a="x" b="y" c="z">
  this is a
  <aabb/>
  content
  <ccdd/>
  string
</tag>
Run Code Online (Sandbox Code Playgroud)

它只解析内容的第一部分("这是一个"),而忽略了这些单个标记之后的所有内容.无论这些单个标签中有多少个跟随,如果它只有一个标签,它也会跳过其余标签.我没有真正得到这种行为,是否有解释或方法来克服这个问题?

Vik*_*ica 5

由于你没有添加任何代码,我创建了自己的测试代码,但没有找到任何问题

import <Foundation/Foundation.h>

@interface ParseDelegate : NSObject  <NSXMLParserDelegate>
@property (nonatomic, copy) NSString *parsedText;
@end

@implementation ParseDelegate {
    NSMutableString *_string;
}

- (id)init {
    if (self = [super init]){
     _string = [@"" mutableCopy];
    }
    return self;
}


- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    [_string appendString:[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
    [_string appendString:@" "];
}

- (void)parserDidEndDocument:(NSXMLParser *)parser {
    self.parsedText = _string;
}
@end

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        ParseDelegate *parseDelegate = [ParseDelegate new];
        NSString *str = @"<tag a=\"x\" b=\"y\" c=\"z\">\n"
                "  this is a\n"
                "  <aabb/>\n"
                "  content\n"
                "  <ccdd/>\n"
                "  string\n"
                "</tag>";
        NSXMLParser *parser = [[NSXMLParser alloc] initWithData:[str dataUsingEncoding:NSUTF8StringEncoding]];
        parser.delegate = parseDelegate;
        [parser parse];
        NSLog(@"%@", parseDelegate.parsedText);
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

结果如预期的那样 this is a content string


如果您实现…:didStart… …:didEnd…委托方法,您将看到正确处理单个标记

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
        NSLog(@"start %@", elementName);
    }

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    NSLog(@"end %@", elementName);
}
Run Code Online (Sandbox Code Playgroud)

结果是

start tag
start aabb
end aabb
start ccdd
end ccdd
end tag
Run Code Online (Sandbox Code Playgroud)

检查你可以做的错误

if([parser parse]){
    NSLog(@"%@", parseDelegate.parsedText);
} else {
    NSLog(@"%@", parser.parserError);
}
Run Code Online (Sandbox Code Playgroud)

通过代理提供另一个错误检查.如果发生错误,它将被发送到委托方法parser:parseErrorOccurred:

该错误包含一个代码.有94种不同的代码.由于出色的IDE AppCode 2,很容易创建一个涵盖所有这些的开关语句,而你如何处理它们取决于你:

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
    NSXMLParserError code = parseError.code;
    switch (code)
    {
        case NSXMLParserTagNameMismatchError:
            NSLog(@"NSXMLParserTagNameMismatchError");
            break;
        case NSXMLParserInternalError:break;
        case NSXMLParserOutOfMemoryError:break;
        case NSXMLParserDocumentStartError:break;
        case NSXMLParserEmptyDocumentError:break;
        case NSXMLParserPrematureDocumentEndError:break;
        case NSXMLParserInvalidHexCharacterRefError:break;
        case NSXMLParserInvalidDecimalCharacterRefError:break;
        case NSXMLParserInvalidCharacterRefError:break;
        case NSXMLParserInvalidCharacterError:break;
        case NSXMLParserCharacterRefAtEOFError:break;
        case NSXMLParserCharacterRefInPrologError:break;
        case NSXMLParserCharacterRefInEpilogError:break;
        case NSXMLParserCharacterRefInDTDError:break;
        case NSXMLParserEntityRefAtEOFError:break;
        case NSXMLParserEntityRefInPrologError:break;
        case NSXMLParserEntityRefInEpilogError:break;
        case NSXMLParserEntityRefInDTDError:break;
        case NSXMLParserParsedEntityRefAtEOFError:break;
        case NSXMLParserParsedEntityRefInPrologError:break;
        case NSXMLParserParsedEntityRefInEpilogError:break;
        case NSXMLParserParsedEntityRefInInternalSubsetError:break;
        case NSXMLParserEntityReferenceWithoutNameError:break;
        case NSXMLParserEntityReferenceMissingSemiError:break;
        case NSXMLParserParsedEntityRefNoNameError:break;
        case NSXMLParserParsedEntityRefMissingSemiError:break;
        case NSXMLParserUndeclaredEntityError:break;
        case NSXMLParserUnparsedEntityError:break;
        case NSXMLParserEntityIsExternalError:break;
        case NSXMLParserEntityIsParameterError:break;
        case NSXMLParserUnknownEncodingError:break;
        case NSXMLParserEncodingNotSupportedError:break;
        case NSXMLParserStringNotStartedError:break;
        case NSXMLParserStringNotClosedError:break;
        case NSXMLParserNamespaceDeclarationError:break;
        case NSXMLParserEntityNotStartedError:break;
        case NSXMLParserEntityNotFinishedError:break;
        case NSXMLParserLessThanSymbolInAttributeError:break;
        case NSXMLParserAttributeNotStartedError:break;
        case NSXMLParserAttributeNotFinishedError:break;
        case NSXMLParserAttributeHasNoValueError:break;
        case NSXMLParserAttributeRedefinedError:break;
        case NSXMLParserLiteralNotStartedError:break;
        case NSXMLParserLiteralNotFinishedError:break;
        case NSXMLParserCommentNotFinishedError:break;
        case NSXMLParserProcessingInstructionNotStartedError:break;
        case NSXMLParserProcessingInstructionNotFinishedError:break;
        case NSXMLParserNotationNotStartedError:break;
        case NSXMLParserNotationNotFinishedError:break;
        case NSXMLParserAttributeListNotStartedError:break;
        case NSXMLParserAttributeListNotFinishedError:break;
        case NSXMLParserMixedContentDeclNotStartedError:break;
        case NSXMLParserMixedContentDeclNotFinishedError:break;
        case NSXMLParserElementContentDeclNotStartedError:break;
        case NSXMLParserElementContentDeclNotFinishedError:break;
        case NSXMLParserXMLDeclNotStartedError:break;
        case NSXMLParserXMLDeclNotFinishedError:break;
        case NSXMLParserConditionalSectionNotStartedError:break;
        case NSXMLParserConditionalSectionNotFinishedError:break;
        case NSXMLParserExternalSubsetNotFinishedError:break;
        case NSXMLParserDOCTYPEDeclNotFinishedError:break;
        case NSXMLParserMisplacedCDATAEndStringError:break;
        case NSXMLParserCDATANotFinishedError:break;
        case NSXMLParserMisplacedXMLDeclarationError:break;
        case NSXMLParserSpaceRequiredError:break;
        case NSXMLParserSeparatorRequiredError:break;
        case NSXMLParserNMTOKENRequiredError:break;
        case NSXMLParserNAMERequiredError:break;
        case NSXMLParserPCDATARequiredError:break;
        case NSXMLParserURIRequiredError:break;
        case NSXMLParserPublicIdentifierRequiredError:break;
        case NSXMLParserLTRequiredError:break;
        case NSXMLParserGTRequiredError:break;
        case NSXMLParserLTSlashRequiredError:break;
        case NSXMLParserEqualExpectedError:break;
        case NSXMLParserUnfinishedTagError:break;
        case NSXMLParserStandaloneValueError:break;
        case NSXMLParserInvalidEncodingNameError:break;
        case NSXMLParserCommentContainsDoubleHyphenError:break;
        case NSXMLParserInvalidEncodingError:break;
        case NSXMLParserExternalStandaloneEntityError:break;
        case NSXMLParserInvalidConditionalSectionError:break;
        case NSXMLParserEntityValueRequiredError:break;
        case NSXMLParserNotWellBalancedError:break;
        case NSXMLParserExtraContentError:break;
        case NSXMLParserInvalidCharacterInEntityError:break;
        case NSXMLParserParsedEntityRefInInternalError:break;
        case NSXMLParserEntityRefLoopError:break;
        case NSXMLParserEntityBoundaryError:break;
        case NSXMLParserInvalidURIError:break;
        case NSXMLParserURIFragmentError:break;
        case NSXMLParserNoDTDError:break;
        case NSXMLParserDelegateAbortedParseError:break;
        default:
            break;
    }


}
Run Code Online (Sandbox Code Playgroud)