-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathSSYRSSParser.m
executable file
·175 lines (145 loc) · 5.78 KB
/
SSYRSSParser.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#import "SSYRSSParser.h"
#import "NSString+RSS.h"
NSString* const SSYRSSParserErrorDomain = @"SSYRSSParserErrorDomain" ;
@interface SSYRSSParser ()
@property (retain) NSData* data ;
@property (retain) NSError* error ;
@property (retain) NSMutableDictionary* headerItems ;
@property (retain) NSMutableArray* newsItems ;
@property (retain) NSString* version ;
@property (retain) NSMutableArray* currentElementLineage ;
@property (retain) NSMutableString* currentElementValue ;
@property (retain) NSMutableDictionary* currentItem ;
@end
@implementation SSYRSSParser
@synthesize data = m_data ;
@synthesize error = m_error ;
@synthesize headerItems = m_headerItems ;
@synthesize newsItems = m_newsItems ;
@synthesize version = m_version ;
@synthesize currentElementLineage = m_currentElementLineage ;
@synthesize currentElementValue = m_currentElementValue ;
@synthesize currentItem = m_currentItem ;
- (SSYRSSParser*)initWithData:(NSData*)data {
if (data) {
self = [super init] ;
if (self) {
[self setData:data] ;
id object ;
object = [[NSMutableDictionary alloc] init] ;
[self setHeaderItems:object] ;
[object release] ;
object = [[NSMutableArray alloc] init] ;
[self setNewsItems:object] ;
[object release] ;
object = [[NSMutableArray alloc] init] ;
[self setCurrentElementLineage:object] ;
[object release] ;
object = [[NSMutableString alloc] init] ;
[self setCurrentElementValue:object] ;
[object release] ;
object = [[NSMutableDictionary alloc] init] ;
[self setCurrentItem:object] ;
[object release] ;
}
}
return self ;
}
- (BOOL)parseError_p:(NSError**)error_p {
BOOL ok = YES ;
NSXMLParser* parser = [[NSXMLParser alloc] initWithData:[self data]] ;
[parser setDelegate:self] ;
[parser setShouldResolveExternalEntities:YES] ;
[parser parse] ;
[parser release] ;
if ([self error]) {
ok = NO ;
if (error_p) {
*error_p = [self error] ;
}
}
return ok ;
}
- (void) dealloc {
[m_data release] ;
[m_error release] ;
[m_headerItems release] ;
[m_newsItems release] ;
[m_version release] ;
[m_currentElementLineage release] ;
[m_currentElementValue release] ;
[m_currentItem release] ;
[super dealloc] ;
}
#pragma mark * NSXMLParser Delegate Methods
-(void) parser:(NSXMLParser*)parser
didStartElement:(NSString*)elementName
namespaceURI:(NSString*)namespaceURI
qualifiedName:(NSString*)qualifiedName
attributes:(NSDictionary*)attributes {
[[self currentElementLineage] addObject:elementName] ;
if ([[self currentElementLineage] isEqualToArray:@[@"rss"]]) {
[self setVersion:[attributes objectForKey:@"version"]] ;
}
}
- (void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName {
if ([elementName isEqualToString:[[self currentElementLineage] lastObject]]) {
[[self currentElementLineage] removeLastObject] ;
NSString* value ;
if ([[self currentElementLineage] isEqualToArray:@[@"rss", @"channel", @"item"]]) {
value = [[self currentElementValue] copy] ;
[[self currentItem] setObject:value
forKey:elementName] ;
[value release] ;
}
else if ([[self currentElementLineage] isEqualToArray:@[@"rss", @"channel"]]) {
if ([elementName isEqualToString:@"item"]) {
NSDictionary* currentItem = [[self currentItem] copy] ;
[[self newsItems] addObject:currentItem] ;
[currentItem release] ;
[[self currentItem] removeAllObjects] ;
}
else {
value = [[self currentElementValue] copy] ;
[[self headerItems] setObject:value
forKey:elementName] ;
[value release] ;
}
}
[[self currentElementValue] setString:@""] ;
}
else {
[self setError:[NSError errorWithDomain:SSYRSSParserErrorDomain
code:672902
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
@"Element start/end mismatch", NSLocalizedDescriptionKey,
[[self currentElementLineage] lastObject], @"Start",
elementName, @"End",
nil]]] ;
[parser abortParsing] ;
}
}
- (void) parser:(NSXMLParser*)parser
foundCharacters:(NSString*)string {
[[self currentElementValue] appendString:string] ;
}
- (NSData*) parser:(NSXMLParser*)parser
resolveExternalEntityName:(NSString*)name
systemID:(NSString*)systemID {
return nil ;
}
- (void) parser:(NSXMLParser*)parser
parseErrorOccurred:(NSError*)parserError {
NSError* error = [NSError errorWithDomain:SSYRSSParserErrorDomain
code:672901
userInfo:[NSDictionary dictionaryWithObjectsAndKeys:
@"Error occurred while parsing RSS data", NSLocalizedDescriptionKey,
[NSNumber numberWithInteger:(long)[[self data] length]], @"Data Byte Count",
parserError, NSUnderlyingErrorKey,
nil]] ;
[self setError:error] ;
}
@end