<content name="Bikes" last_updated_time="">
<bike name="MGP30" image_url="Mobile_App/images/mgp30_bike_banner.png">
<tspecs>
<image url="images/our-bikes/mgp30.png"/>
<image url="images/our-bikes/mgp30_tech_spec/1.jpg"/>
<image url="images/our-bikes/mgp30_tech_spec/2.jpg"/>
<image url="images/our-bikes/mgp30_tech_spec/3.jpg"/>
<image url="images/our-bikes/mgp30_tech_spec/4.jpg"/>
<image url="images/our-bikes/mgp30_tech_spec/5.jpg"/>
<image url="images/our-bikes/mgp30_tech_spec/6.jpg"/>
<image url="images/our-bikes/mgp30_tech_spec/7.jpg"/>
<spec>
<name>Engine Type</name>
<value>4 strokes liquid cooled DOHC</value>
</spec>
<spec></spec>
<spec></spec>
<spec></spec>
<spec></spec>
<spec></spec>
<spec></spec>
<spec></spec>
<spec></spec>
<spec></spec>
<spec></spec>
<spec></spec>
<spec></spec>
<spec></spec>
</tspecs>
<photos></photos>
<workshop></workshop>
</bike>
<bike name="GP125" image_url="Mobile_App/images/gp125_bike_banner.png"></bike>
</content>
This is the first time I am working with xml parsing using core data.I have the above xml data which i receive from the server. I am not bale to understand how to create the relationships between the entities. How do I parse it and keep storing it using core data.
内容是将Bikes作为子元素的根对象。每个Bike元素都有tspecs,照片和研讨会数据。每个tspec都有一组图像和一组规格数据。每个规范数据都有一个名称和值。
答案 0 :(得分:1)
解析XML是iOS中的一个艰苦过程。使用GDataXML以数组格式将xml解析为相应的字典如下。
#define kBikeName @"name"
#define kBikeImageURL @"image_url"
#define kBikeImages @"image"
#define kURL @"url"
#define kBikeSpecs @"spec"
#define kBikeSpecName @"name"
#define kBikeSpecValue @"value"
NSString *filePath = [[NSBundle mainBundle]pathForResource:@"Bikes" ofType:@"xml"];
NSData *fileData = [NSData dataWithContentsOfFile:filePath];
GDataXMLDocument *document = [[GDataXMLDocument alloc]initWithData:fileData
encoding:NSUTF8StringEncoding
error:nil];
NSArray *tempBikes = [document nodesForXPath:@"//content/bike" error:nil];
NSMutableArray *bikes = [NSMutableArray array];
for (GDataXMLElement *element in tempBikes) {
NSMutableDictionary *bike = [NSMutableDictionary dictionary];
NSString *bikeName = [[element attributeForName:kBikeName] stringValue];
bike[kBikeName] = bikeName;
NSString *imageURL = [[element attributeForName:kBikeImageURL] stringValue];
bike[kBikeImageURL] = imageURL;
NSArray *tempImages = [element nodesForXPath:@"tspecs/image" error:nil];//elementsForName:@"image"];
NSMutableArray *images = [NSMutableArray array];
for (GDataXMLElement *imageElement in tempImages) {
NSString *url = [[imageElement attributeForName:kURL]stringValue];
if (url) {
[images addObject:url];
}
}
if (images) {
bike[@"Images"] = images;
}
NSArray *tempSpecs = [element nodesForXPath:@"tspecs/spec" error:nil];//elementsForName:@"spec"];
NSMutableArray *specs = [NSMutableArray array];
for (GDataXMLElement *specElement in tempSpecs) {
NSMutableDictionary *specDict = [NSMutableDictionary dictionary];
NSString *specName = [[specElement elementsForName:kBikeSpecName][0]stringValue];
if (specName) {
specDict[kBikeSpecName] = specName;
}
NSString *specValue = [[specElement elementsForName:kBikeSpecValue][0]stringValue];
if (specValue) {
specDict[kBikeSpecValue] = specValue;
}
if ([[specDict allKeys] count]) {
[specs addObject:specDict];
}
}
if (specs) {
bike[@"Specs"] = specs;
}
[bikes addObject:bike];
}
NSLog(@"%@",bikes);
现在你有了一些字典对象。你本可以形成NSManagedObject
仪式。但是,如果您希望将来使用JSON,这将提供更多可重用的代码。
至少应该至少有三个实体。如果你想要你也可以创建自行车技术规格,它与自行车有一对一的关系,与图像和规格有一对一的关系。但这似乎没必要。
第三方库MagicalRecord
提供无代码数据导入。但它要求您为您的实体提供唯一ID。
例如:如果有实体Bike
,则应该有bikeID
。 BikeImage
应该bikeImageID
而BikeSpec
应该有bikeSpecID
。由于您没有这些,因此无法使用。但我这样说,好像你决定改变结构,可以包含这些结构以利用这个很棒的功能。
设置实体之间的正确关系和反向关系。枚举解析后的数组。执行以下步骤
这不会限制重复条目的创建。
答案 1 :(得分:0)
这是我常用的模板。不需要第三方框架。其中大部分来自Apple的Event-Driven Programming Guide。我会为任何代码拼写错误道歉,因为我从应用程序中删除了它并试图使它对你来说有些通用。然而,这种联系确实是物质的核心。
@implementation XMLParser
- (XMLParser *) initXMLParser {
appDelegate = (PWMSledUpdateAppDelegate *) [[UIApplication sharedApplication]delegate];
return self;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:@"firstElement"])
{
//You now have your First Element name. I typically use an NSMutableDictionary to house the info
//In your example XML above you'd want to look for "content"
}
else if ([elementName isEqualToString:@"secondElement"])
{
//Second element name. Do something with it.
//In your example XML above you'd want to look for "bike"
}
//else if, etc, etc
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
//"string" is your current element's value.
//using your example the value for content.bike.tspecs.spec.name = "Engine Type"
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:@"firstElement"])
{
NSLog(@"Read key \"%@\" with value \"%@\"",elementName, currentElementValue);
//you've now reached the end of your first element.
return;
}
else if ([elementName isEqualToString:@"secondElement"])
{
//you've now reached the end of your second element.
return;
}
//else if etc, etc
{
NSLog(@"Read key \"%@\" with value \"%@\"",elementName, currentElementValue);
[currUpdate setValue:currentElementValue forKey:elementName];
currentElementValue = nil;
}
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
if ( [elementName isEqualToString:@"firstElement"])
{
if (!myAttributes)
{
NSMutableArray *myAttributes = [[NSMutableArray alloc] init];
}
NSString *myName = [attributeDict objectForKey:@"name"];
NSString *myLastUpdate = [attributeDict objectForKey:@"last_updated_time"];
}
//else it etc, etc
}
关于容纳XML数据我通常使用NSMutableDictionary与具有直观命名约定的自定义类结合运行,因此我可以将其称为myClass.name,myClass.lastUpdated,[myClass.name objectForKey @“MGP30”]。
答案 2 :(得分:0)
只需使用NSXMLParser
类来解析xml文件。使用NSXMLParser类的委托方法。委托可以识别你的元素,元素的开头,元素的结尾,它也识别文档的开头,文档的结尾。
通过检查您的元素名称是否匹配,您可以将您的字符串(即数据)保存到数组&amp;使用该数组添加核心数据
以下委托方法可用于检测元素的属性
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
下面用于检测元素结束的委托方法
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
始终在didEndElement中向数组添加值。
您可以检查当前元素是否匹配
if ([elementName isEqualToString:@"firstElement"])