首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >NSXMLParser不会忽略CDATA

NSXMLParser不会忽略CDATA
EN

Stack Overflow用户
提问于 2013-03-22 17:24:10
回答 3查看 2K关注 0票数 1

我在ios开发和im尝试解析RSS文件(Xml)方面非常新。

这里是xml: (对语言很抱歉)

代码语言:javascript
运行
复制
<item>
<category> General < / category >
<title> killed in a tractor accident , was critically injured windsurfer </ title>
<description>
< ! [ CDATA [
<div> <a href='http://www.ynet.co.il/articles/0,7340,L-4360016,00.html'> <img src = 'http://www.ynet.co. il/PicServer3/2012/11/28/4302844/YOO_8879_a.jpg ' alt =' photo: Yaron Brener 'title =' Amona 'border = '0' width = '116 'height = '116'> </ a> < / div >
] ] >
Tractor driver in his 50s near Kfar Yuval flipped and trapped underneath . Room was critically injured windsurfer hurled rocks because of strong winds and wind surfer after was moderately injured in Netanya
< / description >
<link>
http://www.ynet.co.il/articles/0 , 7340, L- 4360016 , 00.html
< / link >
<pubDate> Fri, 22 Mar 2013 17:10:15 +0200 </ pubDate>
<guid>
http://www.ynet.co.il/articles/0 , 7340, L- 4360016 , 00.html
< / guid >
<tags> Kill , car accidents , surfing < / tags >
< / item >

,这里是我的and解析器代码:

代码语言:javascript
运行
复制
    - (void)parserDidStartDocument:(NSXMLParser *)parser
    {
       self.titles = [[NSMutableArray alloc]init];
       self.descriptions = [[NSMutableArray alloc]init];
        self.links = [[NSMutableArray alloc]init];
    }

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

    if ([elementName isEqualToString:@"title"]) {
        isTitle=YES;
        self.titlesString = [[NSMutableString alloc]init];
    }

    if ([elementName isEqualToString:@"description"]) {
        isDesription = YES;
        self.descriptionString = [NSMutableString string];
        self.data = [NSMutableData data];
    }



}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
    if(isItem && isTitle){
        [self.titlesString appendString:string];
    }
    if (isItem && isDesription) {
        if (self.descriptionString)
            [self.descriptionString appendString:string];
    }






}

- (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock
{
    if (self.data)
        [self.data appendData:CDATABlock];

}


- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if ([elementName isEqualToString:@"item"]) {
        isItem = NO;
        [self.titles addObject:self.titlesString];

        [self.descriptions addObject:self.descriptionString];


    }

    if ([elementName isEqualToString:@"title"]) {
        isTitle=NO;

    }
    if ([elementName isEqualToString:@"description"]) {

        NSString *result = [self.descriptionString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
        NSLog(@"string=%@", result);


        if ([self.data length] > 0)
        {
            NSString *htmlSnippet = [[NSString alloc] initWithData:self.data encoding:NSUTF8StringEncoding];
            NSString *imageSrc = [self firstImgUrlString:htmlSnippet];
            NSLog(@"img src=%@", imageSrc);
            [self.links addObject:imageSrc];
        }



        self.descriptionString = nil;
        self.data = nil;
    }


}

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

    NSTextCheckingResult *result = [regex firstMatchInString:string
                                                     options:0
                                                       range:NSMakeRange(0, [string length])];

    if (result)
        return [string substringWithRange:[result rangeAtIndex:2]];

    return nil;
}

@end

就像我说过我对iPhone开发非常陌生一样,我花了几个小时寻找解决这个问题的方法,但什么也没找到。我决定打开一个话题,然后问几个问题:

One.解析器不会忽略CDATA所做的事情--解析一切。为什么会发生这种情况?正如您所看到的,描述本身并不在cdata中,我只有第一步,但是即使我没有使用foundCDATA:(NSData *) CDATABlock,我也得到了其余的部分。

2.我想拿图像链接,怎么做?我在网上搜索,发现很多指南只解释了使用函数foundCDATA:(NSData *) CDATABlock,但是它是如何使用的呢?我在代码中使用的方式?

请给我一个解释,这样我才能理解,,谢谢!

EN

Stack Overflow用户

回答已采纳

发布于 2013-03-22 18:18:41

在回答你的两个问题时:

  1. 如果您已经实现了foundCDATA,解析器将在该方法中解析description CDATA,而不是在foundCharacters中解析。另一方面,如果您没有实现foundCDATA,则CDATA将被foundCharacters解析。因此,如果不希望foundCharacters解析CDATA,则必须实现foundCDATA
  2. 如果您想要提取HTML,您必须以某种方式解析img。您可以使用Hpple,但我可能只是倾向于使用正则表达式:

  • (NSString *)firstImgUrlString:(NSString *)字符串{ NSError *NSString= NULL;NSRegularExpression *regex = [NSRegularExpression NSError]选项:NSRegularExpressionCaseIn敏感错误:&error];NSTextCheckingResult *result = [regex : string选项:0范围:NSMakeRange(0,字符串长度)];如果(结果)返回[string substringWithRange:result rangeAtIndex:2];返回nil;} 还请参阅this other Stack Overflow answer,其中我演示了Hpple和regex解决方案:

例如,下面是解析描述的NSXMLParserDelegate方法,将文本(不包括CDATA)放在一个字段中,并将CDATA中的图像URL放在另一个变量中。您将不得不修改以适应您的过程,但希望这给您提供了基本的想法:

代码语言:javascript
运行
复制
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    if ([elementName isEqualToString:@"description"])
    {
        self.string = [NSMutableString string];
        self.data = [NSMutableData data];
    }
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
    NSLog(@"%s, parseError=%@", __FUNCTION__, parseError);
}

// In my standard NSXMLParser routine, I leave self.string `nil` when not parsing 
// a particular element, and initialize it if I am parsing. I do it this way
// so only my `didStartElement` and `didEndElement` need to worry about the particulars
// and my `foundCharacters` and `foundCDATA` are simplified. But do it however you
// want.

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    if (self.string)
        [self.string appendString:string];
}

- (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock
{
    if (self.data)
        [self.data appendData:CDATABlock];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if ([elementName isEqualToString:@"description"])
    {
        // get the text (non-CDATA) portion

        // you might want to get rid of the leading and trailing whitespace

        NSString *result = [self.string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
        NSLog(@"string=%@", result);

        // get the img out of the CDATA

        if ([self.data length] > 0)
        {
            NSString *htmlSnippet = [[NSString alloc] initWithData:self.data encoding:NSUTF8StringEncoding];
            NSString *imageSrc = [self firstImgUrlString:htmlSnippet];
            NSLog(@"img src=%@", imageSrc);
        }

        // once I've saved the data where I want to save it, I `nil` out my
        // `string` and `data` properties:

        self.string = nil;
        self.data = nil;
    }
}
票数 1
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15576398

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档