أحاول تحليل XML الذي أحصل عليه من خدمة ويب مع NSXMLParserDelegate
. ال NSObject
أريد وضع البيانات في (سأسميها فقط MyObject
) لديها @property
S التي ليست NSString
S (هناك بعض NSDate
ق ، بعض NSNumber
S ، وربما في مرحلة ما في المستقبل بعض البدائيات).
نظرًا لأن XML عبارة [myObject setValue:currentElementValue forKey:elementName];
في parser:didEndElement:...
, ، وهو ما يعمل بشكل جيد - متى key
هو NSString
). لم أكن أتوقع حقًا أن يعمل هذا ، لكنني اعتقدت أن الأمر يستحق اللقطة.
أسهل شيء يجب فعله هو مجرد ترميز كل ذلك ، لذلك إذا كان لدي "property (nonatomic ، قوي) nsnumber *age ؛" على كائني ، عندما أجد <age>25</age>
جزء من XML الخاص بي ، أفعل MyObject.age = [NSNumber numberWithInt:[currentElementValue intValue]];
. المشكلة في هذا هي أنها جامدة للغاية - أود أن يكون هذا الرمز أكثر ديناميكية من ذلك. لا أريد أن أعرف ما هي جميع خصائص كائني في وقت مبكر.
لقد حاولت أيضًا التحقق من ما class
من الممتلكات ، ثم القيام ببعض التحويل قبل إدخال قيمة (لذلك شيء مثل [myObject setValue:[NSNumber numberWithInt:[currentElementValue intValue] forKey:elementName];
إذا كان العقار isKindOfClass:[NSNumber class]]
. المشكلة في ذلك هي أن هذه هي المرة الأولى التي يتم فيها استخدام الخاصية ، لذلك هي كذلك nil
, ، وبالتالي ليس لديه فئة. لذلك هذا النهج لا يعمل حقا أيضا.
هل أفعل هذا خطأً تمامًا؟ يبدو أنه يجب أن يكون نموذجيًا إلى حد ما للحصول على بيانات من XML ووضعها في غيرNSString
المتغيرات ، لكن لا يبدو لي أن نجعلها تعمل.
إذا احتاج أي شخص إلى رؤية المزيد من التعليمات البرمجية للحصول على فهم أفضل لكيفية إعداد هذا أو ما جربته بالفعل ، فأخبرني بذلك.
تحرير: لقد توصلت إلى مثال سريع على ما أحاول القيام به. افترض أن لدي XML التالي:
<Object>
<ITEM_NUMBER>4</ITEM_NUMBER>
<IS_AWESOME>YES</IS_AWESOME>
<AWESOMENESS>9000.1</AWESOMENESS>
</Object>
أنني أريد التحليل في حالة من MyObject
(و NSObject
فئة فرعية)
@interface MyObject: NSObject
@property (nonatomic, assign) int ITEM_NUMBER;
@property (nonatomic, assign) BOOL IS_AWESOME;
@property (nonatomic, assign) float AWESOMENESS;
@end
و XML ثانية
<OtherObject>
<PRICE>4.99</PRICE>
<QUANTITY>5</QUANTITY>
<FOR_RESALE>NO</FOR_RESALE>
</OtherObject>
سوف يذهب إلى مثال OtherObject
(ايضا NSObject
فئة فرعية)
@interface OtherObject: NSObject
@property (nonatomic, assign) int QUANTITY;
@property (nonatomic, assign) BOOL FOR_RESALE;
@property (nonatomic, assign) float PRICE;
@end
أريد إنشاء محلل "قالب" (الذي لديه @property (nonatomic, strong) NSObject *instance;
وثم NSMutableString *currentElementValue
كإيفار)
...
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
[currentElementValue setString:string];
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([[self.instance valueForKey:elementName] isKindOfClass:int])
{
[self.instance setValue:[currentElementValue intValue] forKey:elementName];
}
else if ([[self.instance valueForKey:elementName] isKindOfClass:float])
{
[self.instance setValue:[currentElementValue floatValue] forKey:elementName];
}
else if ([[self.instance valueForKey:elementName] isKindOfClass:BOOL])
{
[self.instance setValue:[currentElementValue boolValue] forKey:elementName];
}
else if ...
}
...
ثم ، أنا فقط فئة فرعية محلل "القالب" لكل من XMLs المختلفة والكتابة فوق init
الطريقة بحيث
self.instance = [[MyObject alloc] init];
أو
self.instance = [[OtherObject alloc] init];
حسب الاقتضاء. لدي الكثير من خدمات الويب التي أدعوها والتي سأحصل عليها منظمة XML منظمة بشكل مشابه ، لذلك فقط الاضطرار إلى تغيير سطر واحد في محلات كل من كل شيء مرغوب فيه للغاية. إن وجود كل رمز المحلل في فئة "قالب" واحد سيجعل الحفاظ على الكود والقراءة وتصحيح الأخطاء أسهل بكثير.
من الواضح أن المشكلة التي أواجهها isKindOfClass
لا يقبل int
, float
, ، أو BOOL
كما المدخلات. هل هناك أي شيء مشابه يمكنني استخدامه بدلاً من ذلك؟