Fixed OPML string export encoding
This commit is contained in:
@@ -48,5 +48,5 @@ extern NSString *OPMLXMLURLKey; //xmlUrl
|
||||
- (id)attributeForKey:(NSString *)key;
|
||||
|
||||
- (NSString *)recursiveDescription;
|
||||
- (NSString *)exportOPMLAsString;
|
||||
- (NSXMLDocument *)exportXML;
|
||||
@end
|
||||
|
||||
@@ -135,58 +135,41 @@ NSString *OPMLXMLURLKey = @"xmlUrl";
|
||||
return mStr;
|
||||
}
|
||||
|
||||
/// @return Nicely formatted string that can be used to export as @c .opml file.
|
||||
- (NSString *)exportOPMLAsString {
|
||||
NSMutableString *str = [NSMutableString new];
|
||||
[str appendString:
|
||||
@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
@"<opml version=\"1.0\">\n"
|
||||
@" <head>\n"];
|
||||
[self appendHeaderTagsToString:str prefix:@" "];
|
||||
[str appendString:
|
||||
@" </head>\n"
|
||||
@" <body>\n"];
|
||||
/// Can be used to export directly to @c .opml file.
|
||||
- (NSXMLDocument *)exportXML {
|
||||
NSXMLElement *head = [NSXMLElement elementWithName:@"head"];
|
||||
for (NSString *key in _mutableAttributes) {
|
||||
NSString *val = [NSString stringWithFormat:@"%@", _mutableAttributes[key]];
|
||||
[head addChild:[NSXMLElement elementWithName:key stringValue:val]];
|
||||
}
|
||||
|
||||
NSXMLElement *body = [NSXMLElement elementWithName:@"body"];
|
||||
for (RSOPMLItem *child in _mutableChildren) {
|
||||
[child appendChildAttributesToString:str prefix:@" "];
|
||||
[child appendChildToNode:body];
|
||||
}
|
||||
[str appendString:
|
||||
@" </body>\n"
|
||||
@"</opml>"];
|
||||
return str;
|
||||
|
||||
NSXMLElement *opml = [NSXMLElement elementWithName:@"opml"];
|
||||
[opml addAttribute:[NSXMLNode attributeWithName:@"version" stringValue:@"1.0"]];
|
||||
[opml addChild:head];
|
||||
[opml addChild:body];
|
||||
|
||||
NSXMLDocument *xml = [NSXMLDocument documentWithRootElement:opml];
|
||||
xml.version = @"1.0";
|
||||
xml.characterEncoding = @"UTF-8";
|
||||
return xml;
|
||||
}
|
||||
|
||||
/**
|
||||
The header attributes are added as separate tags. Quite opposite to outline items.
|
||||
@note Used by @c exportOPMLAsString.
|
||||
*/
|
||||
- (void)appendHeaderTagsToString:(NSMutableString *)str prefix:(NSString *)prefix {
|
||||
for (NSString *key in _mutableAttributes) {
|
||||
[str appendFormat:@"%1$@<%2$@>%3$@</%2$@>\n", prefix, key, _mutableAttributes[key]];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Create outline items for this @c RSOPMLItem and all children recursively.
|
||||
@note Used by @c exportOPMLAsString.
|
||||
*/
|
||||
- (void)appendChildAttributesToString:(NSMutableString *)str prefix:(NSString *)prefix {
|
||||
/// Recursively add XMLNode children.
|
||||
- (void)appendChildToNode:(NSXMLElement *)parent {
|
||||
NSXMLElement *outline = [NSXMLElement elementWithName:@"outline"];
|
||||
[parent addChild:outline];
|
||||
NSString *name = [self displayName];
|
||||
[str appendFormat:@"%1$@<outline title=\"%2$@\" text=\"%2$@\"", prefix, name]; // name comes first
|
||||
for (NSString *key in _mutableAttributes) {
|
||||
if ([key isEqualToString:OPMLTitleKey] || [key isEqualToString:OPMLTextKey]) {
|
||||
continue;
|
||||
}
|
||||
[str appendFormat:@" %@=\"%@\"", key, _mutableAttributes[key]];
|
||||
[outline addAttribute:[NSXMLNode attributeWithName:OPMLTitleKey stringValue:name]];
|
||||
[outline addAttribute:[NSXMLNode attributeWithName:OPMLTextKey stringValue:name]];
|
||||
[outline setAttributesAsDictionary:_mutableAttributes];
|
||||
for (RSOPMLItem *child in _mutableChildren) {
|
||||
[child appendChildToNode:outline];
|
||||
}
|
||||
[str appendString:@">"];
|
||||
if (_mutableChildren.count > 0) {
|
||||
[str appendString:@"\n"];
|
||||
for (RSOPMLItem *child in _mutableChildren) {
|
||||
[child appendChildAttributesToString:str prefix:[prefix stringByAppendingString:@" "]];
|
||||
}
|
||||
[str appendString:prefix];
|
||||
}
|
||||
[str appendString:@"</outline>\n"];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -46,16 +46,17 @@
|
||||
RSOPMLItem *doc = [RSOPMLItem itemWithAttributes:@{OPMLTitleKey : @"Greetings from CCC",
|
||||
@"dateCreated" : @"2018-12-27 23:12:04 +0100",
|
||||
@"ownerName" : @"RSXML Parser"}];
|
||||
[doc addChild:[RSOPMLItem itemWithAttributes:@{OPMLTitleKey : @"Feed Title 1",
|
||||
[doc addChild:[RSOPMLItem itemWithAttributes:@{OPMLTitleKey : @"Feed \"Title\" 1",
|
||||
OPMLHMTLURLKey : @"http://www.feed1.com/",
|
||||
OPMLXMLURLKey : @"http://www.feed1.com/feed.rss",
|
||||
OPMLTypeKey : @"rss"}]];
|
||||
[doc addChild:[RSOPMLItem itemWithAttributes:@{OPMLTitleKey : @"Feed Title 2",
|
||||
[doc addChild:[RSOPMLItem itemWithAttributes:@{OPMLTitleKey : @"Feed 'Title' 2",
|
||||
OPMLHMTLURLKey : @"http://www.feed2.com/",
|
||||
OPMLXMLURLKey : @"http://www.feed2.com/feed.atom",
|
||||
OPMLTypeKey : @"rss"}]];
|
||||
|
||||
NSString *exportString = [doc exportOPMLAsString];
|
||||
NSXMLDocument *xml = [doc exportXML];
|
||||
NSString *exportString = [xml XMLStringWithOptions:NSXMLNodePrettyPrint];
|
||||
NSLog(@"%@", exportString);
|
||||
|
||||
NSData *importData = [exportString dataUsingEncoding:NSUTF8StringEncoding];
|
||||
@@ -68,7 +69,8 @@
|
||||
XCTAssertNil(error);
|
||||
XCTAssertEqual(document.children.count, 2u);
|
||||
XCTAssertEqualObjects(document.displayName, @"Greetings from CCC");
|
||||
XCTAssertEqualObjects(document.children.firstObject.displayName, @"Feed Title 1");
|
||||
XCTAssertEqualObjects(document.children.firstObject.displayName, @"Feed \"Title\" 1");
|
||||
XCTAssertEqualObjects(document.children.lastObject.displayName, @"Feed 'Title' 2");
|
||||
XCTAssertEqualObjects([document.children.lastObject attributeForKey:OPMLXMLURLKey], @"http://www.feed2.com/feed.atom");
|
||||
|
||||
NSLog(@"%@", [document recursiveDescription]);
|
||||
|
||||
Reference in New Issue
Block a user