iOS NSXMLParsing未经形成的HTML

Mor*_*rom 1 html iphone nsxmlparser ios

这是我的方法体,用于解析由RSS源生成的格式错误的html创建的"img src"图像链接...我知道NSXML只解析XML,但我希望它可以偶然发现这些混乱来找到这些微不足道的内容来自凌乱的HTML的图像链接.

我正在尝试检索src属性中找到的第一个图像链接,我在nsData中的每个名为IMG的元素名称中找到具有src属性,然后将其保存到另一个类中的NSString*img.img标签并不完全相同,例如nsData的实例将只包含一个图像实例,就像其中任何一个一样:

<img class ="ms-rteStyle-photoCredit"src ="www.imagelinkthatineed.com" 我不需要的东西

<img alt =""src ="www.imagelinkineedfortableimagecellpreview" 我不需要的东西

<img class ="ms-rteStyle-photoCredit"src ="www.IneedThisLink.com" 更多我不需要的东西

唯一似乎生成NSLog输出的类是第一个.

如何让解析器方法实际运行?

鉴于有一种方法,你推荐一种不同的,更简单的方式吗?

#import "HtmlParser.h"
#import "ArticleItem.h"

@implementation HtmlParser
@synthesize elementArray;

- (HtmlParser *) InitHtmlByString:(NSString *)string {
//    NSString *description = [NSString string];
NSData *nsData = [[NSData alloc] initWithContentsOfFile:(NSString *)string];
elementArray = [[NSMutableArray alloc] init];
parser = [[NSXMLParser alloc] initWithData:nsData];
parser.delegate = self;
[parser parse];
Run Code Online (Sandbox Code Playgroud)

如果我是NSLog(@"%@",nsData); 在此方法体中,输出吐出原始HTML.

currentHTMLElement = [ArticleItem alloc];
return self;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:@"img src"]) {
    currentHTMLElement = [[ArticleItem alloc] init];
}
NSLog(@"\t%@ found a %@ element", self, elementName);
}
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (!currentHTMLElement)
    currentHTMLElement = [[NSMutableString alloc] initWithString:string];   
NSLog(@"Processing Value: %@", currentHTMLElement);
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName   
{
if ([elementName isEqualToString:@"img src"])
    {
        currentHTMLElement.img = elementName;
        [elementArray addObject:currentHTMLElement];
        currentHTMLElement = nil;
        currentNodeContent = nil;
    }
else
{
    if (currentHTMLElement !=nil && elementName != nil && ([elementName isEqualToString:@"img src"]))
    {
        [currentHTMLElement setValue:currentHTMLElement forKey:elementName];
    }
}
    currentHTMLElement = nil;
}                
@end
Run Code Online (Sandbox Code Playgroud)

谢谢你的想法.

Rob*_*Rob 7

鉴于HTML通常不是格式良好的XML,NSXMLParser可能无法正常工作.如果要解析HTML,可以参考这篇Ray Wenderlich文章,如何在iOS上解析HTML.如果您已按照这些说明并将Hpple添加到项目中,则可以检索图像src属性,如下所示:

#import "TFHpple.h"

- (void)retrieveImageSourceTagsViaHpple:(NSURL *)url
{
    NSData *data = [NSData dataWithContentsOfURL:url];

    TFHpple *parser = [TFHpple hppleWithHTMLData:data];

    NSString *xpathQueryString = @"//img";
    NSArray *nodes = [parser searchWithXPathQuery:xpathQueryString];

    for (TFHppleElement *element in nodes)
    {
        NSString *src = [element objectForKey:@"src"];
        NSLog(@"img src: %@", src);
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,我说这支持自我NSRegularExpression反击的反应(在我最喜欢的Stack Overflow答案的脉络中),如果你想要一个imghtml文件中的标签列表,你可以使用以下有点复杂的常规表达:

- (void)retrieveImageSourceTagsViaRegex:(NSURL *)url
{
    NSString *string = [NSString stringWithContentsOfURL:url
                                                encoding:NSUTF8StringEncoding
                                                   error:nil];

    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(<img\\s[\\s\\S]*?src\\s*?=\\s*?['\"](.*?)['\"][\\s\\S]*?>)+?"
                                                                           options:NSRegularExpressionCaseInsensitive
                                                                             error:&error];

    [regex enumerateMatchesInString:string
                            options:0
                              range:NSMakeRange(0, [string length])
                         usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {

                             NSString *src = [string substringWithRange:[result rangeAtIndex:2]];
                             NSLog(@"img src: %@", src);
                         }];
}
Run Code Online (Sandbox Code Playgroud)

如果你想使用NSXMLParser它,它看起来像这样:

- (void)retrieveImageSourceTagsViaNSXMLParser:(NSURL *)url
{
    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
    parser.delegate = self;
    [parser parse];
}

#pragma mark - NSXMLParserDelegate methods

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    if ([elementName isEqualToString:@"img"])
    {
        NSString *src = attributeDict[@"src"];

        NSLog(@"img src: %@", src);
    }
}
Run Code Online (Sandbox Code Playgroud)

根据我的经验,问题是NSXMLParser解析HTML的成功率低于LibXML2/Hpple.我发现在一些简单的页面上,上面的工作很棒.但在其他情况下,却没有.NSXMLParser最重要的是,虽然很擅长解析格式良好的XML,但我会谨慎使用它来解析HTML.