我在ios开发中非常新,我试着解析一个RSS文件(xml)。
这里是xml:(对不起语言)
<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 >
,这是我的xmlparser代码:
- (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开发还很陌生,我找了几个小时解决它的方法但却一无所获。 我决定打开一个主题,然后提出几个问题:
一个。解析器不会忽略CDATA正在解析的所有内容。 为什么会这样?你可以看到描述本身不在cdata中,我只有第一步,但即使我没有使用foundCDATA,我也得到了其余的:( NSData *)CDATABlock
两个。我想拍摄图片链接,该怎么做?我在网上搜索了一下,发现很多指南只解释了使用函数foundCDATA:(NSData *)CDATABlock 但它是如何使用的?我在代码中使用的方式?
我需要一个解释,以便我能理解,谢谢!
答案 0 :(得分:1)
回答你的两个问题:
如果您已实施foundCDATA
,解析器将解析该方法中的description
CDATA,而不是foundCharacters
。另一方面,如果您尚未实施foundCDATA
,CDATA
将由foundCharacters
进行解析。因此,如果您不希望foundCharacters
解析CDATA
,那么您必须实施foundCDATA
。
如果要提取img
网址,则必须以某种方式解析收到的HTML。你可以使用Hpple,但我可能只是倾向于使用正则表达式:
- (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;
}
另请参阅this other Stack Overflow answer,其中我演示了Hpple和regex解决方案:
作为示例,这里是NSXMLParserDelegate
方法将解析描述,将文本(不包括CDATA)放在一个字段中,并将CDATA中的图像URL放在另一个变量中。你必须修改以适应你的过程,但希望这给你基本的想法:
- (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 :(得分:0)
答案1: 我会同意Rob对这个问题给出的答案。
答案2: 试试这个来获取图片链接......
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if([currentElement isEqualToString:@"img"]) {
NSLog(@"%@",[attributeDict objectForKey:@"src"]);
}
}
答案 2 :(得分:0)
您要提取的图像链接位于CDATA块内,但rss解析器会忽略CDATA块。
如果需要从CDATA中提取字符串,可以在foundCDATA中使用此块:
- (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock
{
NSMutableString *cdstring = [[NSMutableString alloc] initWithData:CDATABlock encoding:NSUTF8StringEncoding];
}
现在mutablestring“cdstring”将包含:
<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>
]]>
现在只需使用stringcontainsstring搜索href ='并提取链接或使用webview来显示
htmlContent = [NSString stringWithFormat:@"%@", cdstring];
[webView loadHTMLString:htmlContent baseURL:nil];