今回は「ChimeraXML」で配列型の要素を解析する方法を解説します。
以下のようなXMLがあります。
[categories]要素は子要素として複数の[category]要素を持っています。
このような形式のXMLをデシリアライズする場合、[ChimeraXML]ではNSArray型のプロパティを使用します。
まず、先にNSArray型のプロパティに格納する[category]に対応するエンティティを定義します。
[CategoryEntity.h]
[CategoryEntity.m]
[goods]要素に対応するGoodsEntityにはNSArray型のcategoriesプロパティを定義します。
[GoodsEntity.h]
実装ファイルでは、categoriesプロパティの詳細情報を[propertyInfoForElement:]の戻り値として
解析エンジンに提供する必要があります。
[GoodsEntity.m]
[category]要素に対応するプロパティのメタ情報として、CPPropertyInfo型のオブジェクトを返却します。
CPPropertyInfoのnameプロパティには、プロパティ名を設定します。
そして、childTypeに、NSArrayに格納するオブジェクトの型を指定します。ここでは、CategoryEntity型を指定しています。
Objective-CにはJavaのようにジェネリックコレクションの仕組が無いため、childTypeにより、
解析エンジンに子要素の型情報を提供しているのです。
childTypeにはサンプルのようにCPXmlEntityクラスを継承するクラスの他、
NSStringとNSNumber型を指定することが出来ます。
その場合、解析対象のXMLは以下のような形になります。
解析を実行する処理はこれまでの例と同じです。
NSArray型のプロパティには、実際にはNSMutableArray型のオブジェクトが設定されます。
以下のXMLを見てください。[goods]要素の子要素として、[category]要素が
複数回出現します。上記のサンプルとの違いは、[category]要素の上に
[categories]要素が存在しているかどうかです。
上記のように、暗黙的な配列型要素を解析する場合、コードを少し変更する必要があります。
[GoodsEntity]の[propertyInfoForElement:]メソッドを以下のように変更します。
CPPropertyInfoのimplicitArrayにYESを設定します。
また、要素名が[category]に対して、配列型のプロパティが対応するように変更しています。
以下のようなXMLがあります。
<goods> <goods-name>iPhone5S</goods-name> <categories> <category> <category-code>001</category-code> <category-name>telephone</category-name> </category> <category> <category-code>002</category-code> <category-name>music player</category-name> </category> </categories> </goods>
[categories]要素は子要素として複数の[category]要素を持っています。
このような形式のXMLをデシリアライズする場合、[ChimeraXML]ではNSArray型のプロパティを使用します。
まず、先にNSArray型のプロパティに格納する[category]に対応するエンティティを定義します。
[CategoryEntity.h]
#import "CPXmlEntity.h" @interface CategoryEntity : CPXmlEntity @property(strong,nonatomic) NSString *categoryCode; @property(strong,nonatomic) NSString *categoryName; @end
[CategoryEntity.m]
#import "CategoryEntity.h" @implementation CategoryEntity + (id)propertyInfoForElement:(NSString *)element { static NSDictionary *propDic; if(!propDic){ propDic = @{ @"category-code": @"categoryCode", @"category-name": @"categoryName" }; } return propDic[element]; } @end
[goods]要素に対応するGoodsEntityにはNSArray型のcategoriesプロパティを定義します。
[GoodsEntity.h]
#import "CPXmlEntity.h" @interface GoodsEntity : CPXmlEntity @property(strong,nonatomic) NSString *goodsName; @property(strong,nonatomic) NSArray *categories; @end
実装ファイルでは、categoriesプロパティの詳細情報を[propertyInfoForElement:]の戻り値として
解析エンジンに提供する必要があります。
[GoodsEntity.m]
#import "GoodsEntity.h" #import "CategoryEntity.h" @implementation GoodsEntity + (id)propertyInfoForElement:(NSString *)element { static NSDictionary *propDic; if(!propDic){ CPPropertyInfo *categories = [[CPPropertyInfo alloc] init]; categories.name = @"categories"; categories.childType = [CategoryEntity class]; propDic = @{ @"goods-name": @"goodsName", @"categories": categories }; } return propDic[element]; } @end
[category]要素に対応するプロパティのメタ情報として、CPPropertyInfo型のオブジェクトを返却します。
CPPropertyInfoのnameプロパティには、プロパティ名を設定します。
そして、childTypeに、NSArrayに格納するオブジェクトの型を指定します。ここでは、CategoryEntity型を指定しています。
Objective-CにはJavaのようにジェネリックコレクションの仕組が無いため、childTypeにより、
解析エンジンに子要素の型情報を提供しているのです。
childTypeにはサンプルのようにCPXmlEntityクラスを継承するクラスの他、
NSStringとNSNumber型を指定することが出来ます。
その場合、解析対象のXMLは以下のような形になります。
<goods> <goods-name>iPhone5S</goods-name> <categories> <category-code>001</category-code> <category-code>002</category-code> </categories> </goods>
解析を実行する処理はこれまでの例と同じです。
NSData *data = [xmlText dataUsingEncoding:NSUTF8StringEncoding]; ChimeraParser *chimeraParser = [[ChimeraParser alloc] initWithTargetClass:[GoodsEntity class]]; GoodsEntity *goods = [chimeraParser parse:data]; NSLog(@"goodsName = %@",goods.goodsName); for(id category in goods.categories) { NSLog(@"categoryCode = %@",[category categoryCode]); NSLog(@"categoryName = %@",[category categoryName]); }
NSArray型のプロパティには、実際にはNSMutableArray型のオブジェクトが設定されます。
暗黙的な配列の解析
以下のXMLを見てください。[goods]要素の子要素として、[category]要素が
複数回出現します。上記のサンプルとの違いは、[category]要素の上に
[categories]要素が存在しているかどうかです。
<goods> <goods-name>iPhone5S</goods-name> <category> <category-code>001</category-code> <category-name>telephone</category-name> </category> <category> <category-code>002</category-code> <category-name>music player</category-name> </category> </goods>
上記のように、暗黙的な配列型要素を解析する場合、コードを少し変更する必要があります。
[GoodsEntity]の[propertyInfoForElement:]メソッドを以下のように変更します。
+ (id)propertyInfoForElement:(NSString *)element { static NSDictionary *propDic; if(!propDic){ CPPropertyInfo *categories = [[CPPropertyInfo alloc] init]; categories.name = @"categories"; categories.childType = [CategoryEntity class]; categories.implicitArray = YES; //この行を追加 propDic = @{ @"goods-name": @"goodsName", //@"categories": categories @"category": categories //対応する要素名を変更 }; } return propDic[element]; }
CPPropertyInfoのimplicitArrayにYESを設定します。
また、要素名が[category]に対して、配列型のプロパティが対応するように変更しています。
ChimeraXMLチュートリアル(1) シンプルなXMLを解析する
ChimeraXMLチュートリアル(2) エンティティ型のプロパティを定義する
ChimeraXML_チュートリアル(3) 配列型の要素を解析する
ChimeraXMLチュートリアル(2) エンティティ型のプロパティを定義する
ChimeraXML_チュートリアル(3) 配列型の要素を解析する
コメント
コメントの投稿
トラックバック
http://csfun.blog49.fc2.com/tb.php/129-376c9696