iOS NSXMLParsing未经形成的HTML

时间:2013-02-13 19:41:53

标签: iphone html ios nsxmlparser

这是我的方法体,用于解析由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];

如果我是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

感谢您的想法。

1 个答案:

答案 0 :(得分:7)

鉴于HTML通常不是格式良好的XML,NSXMLParser可能无效。如果要解析HTML,可以参考Ray Wenderlich的这篇文章How to Parse HTML on iOS。如果您已按照这些说明并将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);
    }
}

另外,如果你想要一个NSRegularExpression标签清单,我说这可以让我自己反击{img反应的冲击(在我的all-time favorite Stack Overflow answer的脉络中) html文件,你可以使用下面有点复杂的正则表达式:

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

如果你想使用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);
    }
}

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