ios - Cómo implementar este método en mi NSXMLParser para extraer imágenes
uiimageview cdata (1)
En su ejemplo, solo tiene dos elementos de description
, cada uno con la etiqueta img
incrustada en él. Simplemente analiza la description
como normal, y luego saca las etiquetas img
(usando expresiones regulares, usando my retrieveImageSourceTagsViaRegex
continuación, o un escáner).
Tenga en cuenta que no es necesario que maneje las representaciones CDATA
y no CDATA
diferente si no desea. Si bien NSXMLParserDelegate
proporciona una rutina foundCDATA
, en realidad me inclino a no implementar eso. En ausencia de un foundCDATA
, la rutina foundCharacters
estándar de foundCharacters
NSXMLParser
con gracia ambas representaciones de su etiqueta de description
(con y sin CDATA
) sin problemas.
Considere el siguiente XML hipotético:
<xml>
<descriptions>
<description><![CDATA[ <p>Roger Craig Smith and Troy Baker to play Batman and the Joker respectively in upcoming action game; Deathstroke confirmed as playable character. </p><p><img src="http://image.com.com/gamespot/images/2013/139/ArkhamOrigins_29971_thumb.jpg">]]></description>
<description><img src="http://cdn.gsmarena.com/vv/newsimg/13/05/samsung-galaxy-s4-active-photos/thumb.jpg" width="70" height="92" hspace="3" alt="" border="0" align=left style="background:#333333;padding:0px;margin:0px 4px 0px 0px;border-style:solid;border-color:#aaaaaa;border-width:1px" /> <p></description>
</descriptions>
</xml>
El siguiente analizador analizará las dos entradas de description
y tomará las URL de imagen de ellas. Y como verá, no es necesario un manejo especial para CDATA
:
@interface ViewController () <NSXMLParserDelegate>
@property (nonatomic, strong) NSMutableString *description;
@property (nonatomic, strong) NSMutableArray *results;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSURL *filename = [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"xml"];
NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:filename];
parser.delegate = self;
[parser parse];
// full array of dictionary entries
NSLog(@"results = %@", self.results);
}
- (NSMutableArray *)retrieveImageSourceTagsViaRegex:(NSString *)string
{
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(<img//s[//s//S]*?src//s*?=//s*?[''/"](.*?)[''/"][//s//S]*?>)+?"
options:NSRegularExpressionCaseInsensitive
error:&error];
NSMutableArray *results = [NSMutableArray array];
[regex enumerateMatchesInString:string
options:0
range:NSMakeRange(0, [string length])
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
[results addObject:[string substringWithRange:[result rangeAtIndex:2]]];
}];
return results;
}
#pragma mark - NSXMLParserDelegate
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
self.results = [NSMutableArray array];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:@"description"])
self.description = [NSMutableString string];
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (self.description)
[self.description appendString:string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:@"description"])
{
NSArray *imgTags = [self retrieveImageSourceTagsViaRegex:self.description];
NSDictionary *result = @{@"description": self.description, @"imgs" : imgTags};
[self.results addObject:result];
self.description = nil;
}
}
@end
Eso produce los siguientes resultados (nota, no CDATA
):
results = (
{
description = " <p>Roger Craig Smith and Troy Baker to play Batman and the Joker respectively in upcoming action game; Deathstroke confirmed as playable character. </p><p><img src=/"http://image.com.com/gamespot/images/2013/139/ArkhamOrigins_29971_thumb.jpg/">";
imgs = (
"http://image.com.com/gamespot/images/2013/139/ArkhamOrigins_29971_thumb.jpg"
);
},
{
description = "<img src=/"http://cdn.gsmarena.com/vv/newsimg/13/05/samsung-galaxy-s4-active-photos/thumb.jpg/" width=/"70/" height=/"92/" hspace=/"3/" alt=/"/" border=/"0/" align=left style=/"background:#333333;padding:0px;margin:0px 4px 0px 0px;border-style:solid;border-color:#aaaaaa;border-width:1px/" /> <p>";
imgs = (
"http://cdn.gsmarena.com/vv/newsimg/13/05/samsung-galaxy-s4-active-photos/thumb.jpg"
);
}
)
Por lo tanto, en resumen, simplemente analice el XML como es normal, no se preocupe por CDATA
, y simplemente analice la URL de la imagen usando un NSScanner
o NSRegularExpression
como mejor le parezca.
Soy nuevo en el desarrollo de iOS, y en este momento he implementado el NSXMLparser, pero realmente no sé cómo separar etiquetas con el mismo nombre, pero con contenido diferente, como la <description>
. En algunos feeds, esta etiqueta solo tiene el resumen y en otro contiene el "img src", que también quiero extraer. (con o sin CDATA)
Example of description tags wich i need to grab the images and then pass to my UIImageView:
<description><![CDATA[ <p>Roger Craig Smith and Troy Baker to play Batman and the Joker respectively in upcoming action game; Deathstroke confirmed as playable character. </p><p><img src="http://image.com.com/gamespot/images/2013/139/ArkhamOrigins_29971_thumb.jpg"
<description><img src="http://cdn.gsmarena.com/vv/newsimg/13/05/samsung-galaxy-s4-active-photos/thumb.jpg" width="70" height="92" hspace="3" alt="" border="0" align=left style="background:#333333;padding:0px;margin:0px 4px 0px 0px;border-style:solid;border-color:#aaaaaa;border-width:1px" /> <p>
Creo que el ejemplo de @Rob soluciona mi caso, pero no sé cómo incluirlo en mi NSXMLParser, que se describe a continuación, para separar datos e imágenes. Puedo obtener solo los datos (resumen) en este analizador.
Mi NSXMLParser:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
element = [elementName copy];
if ([elementName isEqualToString:@"item"])
{
elements = [[NSMutableDictionary alloc] init];
title = [[NSMutableString alloc] init];
date = [[NSMutableString alloc] init];
summary = [[NSMutableString alloc] init];
link = [[NSMutableString alloc] init];
img = [[NSMutableString alloc] init];
imageLink = [[NSMutableString alloc]init];
}
if([elementName isEqualToString:@"media:thumbnail"]) {
NSLog(@"thumbnails media:thumbnail: %@", attributeDict);
imageLink = [attributeDict objectForKey:@"url"];
}
if([elementName isEqualToString:@"media:content"]) {
NSLog(@"thumbnails media:content: %@", attributeDict);
imageLink = [attributeDict objectForKey:@"url"];
}
if([elementName isEqualToString:@"enclosure"]) {
NSLog(@"thumbnails Enclosure %@", attributeDict);
imageLink = [attributeDict objectForKey:@"url"];
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if ([element isEqualToString:@"title"])
{
[title appendString:string];
}
else if ([element isEqualToString:@"pubDate"])
{
[date appendString:string];
}
else if ([element isEqualToString:@"description"])
{
[summary appendString:string];
}
else if ([element isEqualToString:@"media:description"])
{
[summary appendString:string];
}
else if ([element isEqualToString:@"link"])
{
[link appendString:string];
}
else if ([element isEqualToString:@"url"]) {
[imageLink appendString:string];
}
else if ([element isEqualToString:@"src"]) {
[imageLink appendString:string];
}
else if ([element isEqualToString:@"content:encoded"]){
NSString *imgString = [self getImage:string];
if (imgString != nil) {
[img appendString:imgString];
NSLog(@"Content of img:%@", img);
}
}
-(NSString *) getImage:(NSString *)htmlString {
NSString *url = nil;
NSScanner *theScanner = [NSScanner scannerWithString:htmlString];
[theScanner scanUpToString:@"<img" intoString:nil];
if (![theScanner isAtEnd]) {
[theScanner scanUpToString:@"src" intoString:nil];
NSCharacterSet *charset = [NSCharacterSet characterSetWithCharactersInString:@"/"''"];
[theScanner scanUpToCharactersFromSet:charset intoString:nil];
[theScanner scanCharactersFromSet:charset intoString:nil];
[theScanner scanUpToCharactersFromSet:charset intoString:&url];
}
return url;
}
@end