Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: twg/Mantle
...
head fork: twg/Mantle
Checking mergeability… Don't worry, you can still create the pull request.
  • 2 commits
  • 7 files changed
  • 0 commit comments
  • 1 contributor
View
3  .gitmodules
@@ -7,6 +7,3 @@
[submodule "Configuration"]
path = Configuration
url = https://github.com/jspahrsummers/xcconfigs.git
-[submodule "Mantle/rapturexml"]
- path = Mantle/rapturexml
- url = https://github.com/ZaBlanc/RaptureXML.git
View
4 Mantle.xcodeproj/project.pbxproj
@@ -1046,7 +1046,6 @@
HEADER_SEARCH_PATHS = (
"MantleTests/specta/src/**",
"MantleTests/expecta/src/**",
- Mantle/rapturexml/Rapturexml,
"\"$(SDK_DIR)\"/usr/include/libxml2",
);
INFOPLIST_FILE = "MantleTests/MantleTests-Info.plist";
@@ -1070,7 +1069,6 @@
HEADER_SEARCH_PATHS = (
"MantleTests/specta/src/**",
"MantleTests/expecta/src/**",
- Mantle/rapturexml/Rapturexml,
"\"$(SDK_DIR)\"/usr/include/libxml2",
);
INFOPLIST_FILE = "MantleTests/MantleTests-Info.plist";
@@ -1152,7 +1150,6 @@
HEADER_SEARCH_PATHS = (
"MantleTests/specta/src/**",
"MantleTests/expecta/src/**",
- Mantle/rapturexml/Rapturexml,
"\"$(SDK_DIR)\"/usr/include/libxml2",
);
INFOPLIST_FILE = "MantleTests/MantleTests-Info.plist";
@@ -1278,7 +1275,6 @@
HEADER_SEARCH_PATHS = (
"MantleTests/specta/src/**",
"MantleTests/expecta/src/**",
- Mantle/rapturexml/Rapturexml,
"\"$(SDK_DIR)\"/usr/include/libxml2",
);
INFOPLIST_FILE = "MantleTests/MantleTests-Info.plist";
View
3  Mantle.xcworkspace/contents.xcworkspacedata
@@ -10,7 +10,4 @@
<FileRef
location = "group:MantleTests/specta/Specta.xcodeproj">
</FileRef>
- <FileRef
- location = "group:Mantle/rapturexml/RaptureXML.xcodeproj">
- </FileRef>
</Workspace>
View
6 Mantle/MTLXMLAdapter.h
@@ -8,7 +8,7 @@
#import <Foundation/Foundation.h>
-@class RXMLElement, MTLModel;
+@class MTLModel;
@protocol MTLXMLSerializable <NSObject>
@@ -33,9 +33,9 @@ extern const NSInteger MTLXMLAdapterErrorInvalidRXMLElement;
@property (strong, nonatomic, readonly) MTLModel *model;
+ (id)modelOfClass:(Class)modelClass
- fromXML:(RXMLElement *)xml
+ fromXML:(NSData *)xml
error:(NSError **)error;
-- (id)initWithXML:(RXMLElement *)xml modelClass:(Class)modelClass error:(NSError **)error;
+- (id)initWithXMLData:(NSData *)xml modelClass:(Class)modelClass error:(NSError **)error;
@end
View
153 Mantle/MTLXMLAdapter.m
@@ -9,9 +9,13 @@
#import "MTLXMLAdapter.h"
#import "MTLModel.h"
-#import "RXMLElement.h"
#import "MTLReflection.h"
+#import <libxml2/libxml/xmlreader.h>
+#import <libxml2/libxml/xmlmemory.h>
+#import <libxml/xpath.h>
+#import <libxml/xpathInternals.h>
+
NSString * const MTLXMLAdapterErrorDomain = @"MTLXMLAdapterErrorDomain";
const NSInteger MTLXMLAdapterErrorNoClassFound = 2;
const NSInteger MTLXMLAdapterErrorInvalidXPathMapping = 3;
@@ -19,6 +23,100 @@
const NSInteger MTLXMLAdapterErrorNoResultXPath = 5;
const NSInteger MTLXMLAdapterErrorInvalidRXMLElement = 6;
+@interface MTLXMLDocument : NSObject {
+ xmlDocPtr doc_;
+ xmlNodePtr node_;
+}
+
+- (id)initWithData:(NSData *)data;
+
+@end
+
+@implementation MTLXMLDocument
+
+- (id)initWithData:(NSData *)data
+{
+ if (self = [super init]) {
+ doc_ = xmlReadMemory([data bytes], (int)[data length], "", nil, XML_PARSE_RECOVER);
+ node_ = xmlDocGetRootElement(doc_);
+ }
+
+ return self;
+}
+
+- (id)initWithXMLDoc:(xmlDocPtr)doc node:(xmlNodePtr)node
+{
+ if (self = [super init]) {
+ doc_ = doc;
+ node_ = node;
+ }
+ return self;
+}
+
+- (NSString *)text {
+ xmlChar *key = xmlNodeGetContent(node_);
+ NSString *text = (key ? [NSString stringWithUTF8String:(const char *)key] : @"");
+ xmlFree(key);
+
+ return text;
+}
+
+- (NSArray *)xpathQuery:(NSString *)xpath error:(NSError **)error
+{
+ NSParameterAssert(xpath);
+
+ xmlXPathContextPtr context = xmlXPathNewContext(doc_);
+
+ if (context == NULL) {
+ return nil;
+ }
+
+ xmlXPathObjectPtr object = xmlXPathEvalExpression((xmlChar *)[xpath cStringUsingEncoding:NSUTF8StringEncoding],
+ context);
+ if(object == NULL) {
+ return nil;
+ }
+
+ xmlNodeSetPtr nodes = object->nodesetval;
+ if (nodes == NULL) {
+ return nil;
+ }
+
+ if (nodes->nodeNr > 1) {
+ if (error != NULL) {
+ NSString *errorReason = [NSString stringWithFormat:NSLocalizedString(@"XPath query: %@ returns ambiguous results. Make sure that the XPath query returns only one result.", nil),
+ NSStringFromClass([self class])];
+
+ NSDictionary *userInfo = @{
+ NSLocalizedDescriptionKey: NSLocalizedString(@"Ambiguous XPath", @""),
+ NSLocalizedFailureReasonErrorKey: errorReason
+ };
+
+ *error = [NSError errorWithDomain:MTLXMLAdapterErrorDomain code:MTLXMLAdapterErrorAmbiguousXPath
+ userInfo:userInfo];
+ }
+
+ return nil;
+ }
+
+ NSMutableArray *resultNodes = [NSMutableArray array];
+
+ for (NSInteger i = 0; i < nodes->nodeNr; i++) {
+ MTLXMLDocument *element = [[MTLXMLDocument alloc] initWithXMLDoc:doc_ node:nodes->nodeTab[i]];
+
+ if (element != NULL) {
+ [resultNodes addObject:element];
+ }
+ }
+
+ xmlXPathFreeObject(object);
+ xmlXPathFreeContext(context);
+
+ return resultNodes;
+}
+
+@end
+
@interface MTLXMLAdapter ()
@property (strong, nonatomic, readonly) Class modelClass;
@@ -29,19 +127,19 @@ @interface MTLXMLAdapter ()
@implementation MTLXMLAdapter
+ (id)modelOfClass:(Class)modelClass
- fromXML:(RXMLElement *)xml
+ fromXML:(NSData *)xml
error:(NSError **)error
{
- MTLXMLAdapter *adapter = [[self alloc] initWithXML:xml modelClass:modelClass error:error];
+ MTLXMLAdapter *adapter = [[self alloc] initWithXMLData:xml modelClass:modelClass error:error];
return adapter.model;
}
-- (id)initWithXML:(RXMLElement *)xml modelClass:(Class)modelClass error:(NSError **)error
+- (id)initWithXMLData:(NSData *)xml modelClass:(Class)modelClass error:(NSError **)error
{
NSParameterAssert(modelClass != nil);
NSParameterAssert([modelClass isSubclassOfClass:MTLModel.class]);
- if (xml == nil || ![xml isKindOfClass:RXMLElement.class]) {
+ if (xml == nil || ![xml isKindOfClass:NSData.class]) {
if (error != NULL) {
NSString *errorReason = [NSString stringWithFormat:NSLocalizedString(@"%@ could not be created because an "
"invalid RXMLelement was provided: %@",
@@ -61,6 +159,8 @@ - (id)initWithXML:(RXMLElement *)xml modelClass:(Class)modelClass error:(NSError
}
if(!(self = [super init])) return nil;
+
+ MTLXMLDocument *xmlDoc = [[MTLXMLDocument alloc] initWithData:xml];
NSMutableDictionary *dictionaryValue = [NSMutableDictionary dictionary];
@@ -87,9 +187,17 @@ - (id)initWithXML:(RXMLElement *)xml modelClass:(Class)modelClass error:(NSError
for (NSString *propertyKey in propertyKeys) {
NSString *XMLXPath = [self XMLXPathForPropertyKey:propertyKey];
if (XMLXPath == nil) continue;
-
- id value = [self nodeFromXPath:XMLXPath onXML:xml error:error];
-
+
+ NSArray *xpathResults = [xmlDoc xpathQuery:XMLXPath error:error];
+ if (*error) return nil;
+
+ id value;
+ if (xpathResults.count > 0) {
+ value = [xpathResults[0] text];
+ } else {
+ value = nil;
+ }
+
if (value == nil) continue;
NSValueTransformer *transformer = [self XMLTransformerForKey:propertyKey];
@@ -107,35 +215,6 @@ - (id)initWithXML:(RXMLElement *)xml modelClass:(Class)modelClass error:(NSError
return self;
}
-- (id)nodeFromXPath:(NSString *)XPath onXML:(RXMLElement *)xml error:(NSError **)error
-{
- NSArray *xpathResults = [xml childrenWithRootXPath:XPath];
-
- if (xpathResults.count > 1) {
- if (error != NULL) {
- NSString *errorReason = [NSString stringWithFormat:NSLocalizedString(@"XPath query: %@ returns ambiguous results. Make sure that the XPath query returns only one result.", nil),
- NSStringFromClass(_modelClass), xml.class];
-
- NSDictionary *userInfo = @{
- NSLocalizedDescriptionKey: NSLocalizedString(@"Ambiguous XPath", @""),
- NSLocalizedFailureReasonErrorKey: errorReason
- };
-
- *error = [NSError errorWithDomain:MTLXMLAdapterErrorDomain code:MTLXMLAdapterErrorAmbiguousXPath
- userInfo:userInfo];
-
- }
-
- return nil;
- }
-
- if (xpathResults.count == 0) {
- return nil;
- }
-
- return [xpathResults[0] text];
-}
-
- (NSString *)XMLXPathForPropertyKey:(NSString *)key {
NSParameterAssert(key != nil);
1  Mantle/rapturexml
@@ -1 +0,0 @@
-Subproject commit 76b59ec0abf68c06d27cc027d7750b6a4da08650
View
13 MantleTests/MTLXMLAdapterSpec.m
@@ -15,16 +15,15 @@
//
#import "MTLTestXMLModel.h"
-#import "RXMLElement.h"
SpecBegin(MTLXMLAdapter)
it(@"should initialize from XML", ^{
NSString *values = @"<model><username></username><count>5</count></model>";
- RXMLElement *valuesElement = [RXMLElement elementFromXMLString:values encoding:NSUTF8StringEncoding];
+ NSData *xmlData = [values dataUsingEncoding:NSUTF8StringEncoding];
NSError *error = nil;
- MTLXMLAdapter *adapter = [[MTLXMLAdapter alloc] initWithXML:valuesElement modelClass:MTLTestXMLModel.class error:&error];
+ MTLXMLAdapter *adapter = [[MTLXMLAdapter alloc] initWithXMLData:xmlData modelClass:MTLTestXMLModel.class error:&error];
expect(adapter).notTo.beNil();
expect(error).to.beNil();
@@ -36,10 +35,10 @@
it(@"should initialize nested key paths from JSON", ^{
NSString *values = @"<model><username>foo</username><count></count><nested><name>bar</name></nested></model>";
- RXMLElement *valuesElement = [RXMLElement elementFromXMLString:values encoding:NSUTF8StringEncoding];
+ NSData *xmlData = [values dataUsingEncoding:NSUTF8StringEncoding];
NSError *error = nil;
- MTLTestXMLModel *model = [MTLXMLAdapter modelOfClass:MTLTestXMLModel.class fromXML:valuesElement error:&error];
+ MTLTestXMLModel *model = [MTLXMLAdapter modelOfClass:MTLTestXMLModel.class fromXML:xmlData error:&error];
expect(model).notTo.beNil();
expect(error).to.beNil();
@@ -50,10 +49,10 @@
it(@"should return nil and error with an illegal JSON mapping", ^{
NSString *values = @"<model><username>foo</username></model>";
- RXMLElement *valuesElement = [RXMLElement elementFromXMLString:values encoding:NSUTF8StringEncoding];
+ NSData *xmlData = [values dataUsingEncoding:NSUTF8StringEncoding];
NSError *error = nil;
- MTLIllegalXMLMappingModel *model = [MTLXMLAdapter modelOfClass:MTLIllegalXMLMappingModel.class fromXML:valuesElement error:&error];
+ MTLIllegalXMLMappingModel *model = [MTLXMLAdapter modelOfClass:MTLIllegalXMLMappingModel.class fromXML:xmlData error:&error];
expect(model).beNil();
expect(error).notTo.beNil();
expect(error.domain).to.equal(MTLXMLAdapterErrorDomain);

No commit comments for this range

Something went wrong with that request. Please try again.