【问题标题】:NSXMLParser doesn't parse some of the content [closed]NSXMLParser 不解析某些内容 [关闭]
【发布时间】:2013-04-02 19:42:40
【问题描述】:

我的 iOS 应用程序解析从远程服务器获取的 xml(我无法以任何方式影响)。 当遇到如下xml标签时:

<tag a="x" b="y" c="z">
  this is a
  <aabb/>
  content
  <ccdd/>
  string
</tag>

它只解析内容的第一部分(“这是一个”),而忽略了这些单个标签之后的所有内容。这些单个标签中有多少个无关紧要,如果它只有一个标签,它也会跳过其余部分。我真的不明白这种行为,是否有解释或方法来克服这个问题?

【问题讨论】:

  • 您没有注意到代码第 5 行的错误吗?
  • 如果你想解析它:&lt;irony&gt;didnt you notice the error in the 5th line of your code? &lt;/irony&gt;
  • 当你没有显示你的代码时,谁能指出问题?
  • 对不起,伙计们,但我的代码不过是 NSXMLParser 的标准实现、添加内容的字符串属性等等......我认为这会严重浪费这里的空间......
  • @LaK,由于解析器使用委托,因此几乎没有标准实现。

标签: objective-c cocoa-touch nsxmlparser


【解决方案1】:

由于您没有添加任何代码,因此我创建了自己的测试代码并找不到任何问题

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;
}

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);
}

结果

start tag
start aabb
end aabb
start ccdd
end ccdd
end tag

检查你可以做的错误

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

另一个错误检查是通过委托提供的。如果发生错误,将发送到委托方法parser:parseErrorOccurred:

错误包含代码。 There are 94 different codes。多亏了出色的 IDE AppCode 2,很容易创建一个涵盖所有这些的 switch 语句,而如何处理它们取决于你。:

- (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;
    }


}

【讨论】:

  • +2 表示出色、全面的答案,-1 表示没有大写和标点符号。
  • @Caleb:请随时纠正非英语母语人士。
  • 感谢您的出色回答。我以前检查过那些东西,但奇怪的是它没有任何问题。我想我会再次手动检查提供给我的 xml,可能他们的 xml 中存在一致性问题,但这不会导致解析器错误吗?不过答案很好,感谢您的提示。
  • @LaK:查看我的编辑以了解如何检查错误
  • 好的,谢谢!解析的 xml 中存在一些偏差,导致区分大小写的代码出现问题。谢谢!!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 2013-02-10
  • 2012-02-12
  • 2015-09-30
相关资源
最近更新 更多