From 804bc1a6c719512c4ee0da597ff2dcac1ab3ae58 Mon Sep 17 00:00:00 2001 From: relikd Date: Tue, 22 Jan 2019 03:45:23 +0100 Subject: [PATCH] Fixed OPML string export encoding --- RSXML/RSOPMLItem.h | 2 +- RSXML/RSOPMLItem.m | 75 ++++++++++++++++------------------------ RSXMLTests/RSOPMLTests.m | 10 +++--- 3 files changed, 36 insertions(+), 51 deletions(-) diff --git a/RSXML/RSOPMLItem.h b/RSXML/RSOPMLItem.h index b974335..cd82e5c 100644 --- a/RSXML/RSOPMLItem.h +++ b/RSXML/RSOPMLItem.h @@ -48,5 +48,5 @@ extern NSString *OPMLXMLURLKey; //xmlUrl - (id)attributeForKey:(NSString *)key; - (NSString *)recursiveDescription; -- (NSString *)exportOPMLAsString; +- (NSXMLDocument *)exportXML; @end diff --git a/RSXML/RSOPMLItem.m b/RSXML/RSOPMLItem.m index 72f7813..3fef2f3 100644 --- a/RSXML/RSOPMLItem.m +++ b/RSXML/RSOPMLItem.m @@ -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: - @"\n" - @"\n" - @" \n"]; - [self appendHeaderTagsToString:str prefix:@" "]; - [str appendString: - @" \n" - @" \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: - @" \n" - @""]; - 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$@\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$@"]; - if (_mutableChildren.count > 0) { - [str appendString:@"\n"]; - for (RSOPMLItem *child in _mutableChildren) { - [child appendChildAttributesToString:str prefix:[prefix stringByAppendingString:@" "]]; - } - [str appendString:prefix]; - } - [str appendString:@"\n"]; } @end diff --git a/RSXMLTests/RSOPMLTests.m b/RSXMLTests/RSOPMLTests.m index 3cdb9b4..3635c47 100644 --- a/RSXMLTests/RSOPMLTests.m +++ b/RSXMLTests/RSOPMLTests.m @@ -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]);