
Parsing XML in NSDictionary with libxml
In the project for iPhone, I encountered the need to parse a large number of xml responses from the server. I would like to share my solution for parsing XML in NSDictionary.
XML of the form (some root element must be present, in the result example): it will be converted to: Actually the methods themselves: I have in my self.content the xml received from the Internet (from where, in principle, it doesn’t matter) in NSData. If there is no root element in xml, then you will have to redo the code a bit, parse each element in NSDictionary and “add” it to NSArray, but with this structure of the result, to put it mildly, it is not convenient to work with the result. I hope I helped someone, and maybe I will hear criticism and suggestions from someone.
There is a problem, libxml gives insignificant faces, most likely the faces of the library itself.
XML of the form (some root element must be present, in the result example): it will be converted to: Actually the methods themselves: I have in my self.content the xml received from the Internet (from where, in principle, it doesn’t matter) in NSData. If there is no root element in xml, then you will have to redo the code a bit, parse each element in NSDictionary and “add” it to NSArray, but with this structure of the result, to put it mildly, it is not convenient to work with the result. I hope I helped someone, and maybe I will hear criticism and suggestions from someone.
- Value
- value
NSDictionary {
"name" => "result",
"attr" => NSDictionary {
"success" => "true"
},
"child" => NSArray {
0 => NSDictionary {
"name" => "item",
"value" => "value"
},
1 => NSDictionary {
"name" => "item",
"attr" => NSDictionary {
"code" => "item"
}
},
2 => NSDictionary {
"name" => "item",
"attr" => NSDictionary {
"attr" => "val"
},
"value" => "value"
}
}
/* преобразование xml в массив */
- (NSDictionary *)xmlToDict {
NSDictionary *resultDict = [NSDictionary dictionary];
if (self.content != nil) {
xmlDocPtr doc = xmlParseMemory([self.content bytes], [self.content length]);
if (!doc) {
// сообщение об ошибке
NSLog(@"error");
}
else {
xmlNode *root = NULL;
root = xmlDocGetRootElement(doc);
resultDict = [NSDictionary dictionaryWithDictionary:[self getNodeInfo:root]];
xmlFree(root);
}
}
return resultDict;
}
/* информация об xml объекте, рекурсия */
-(NSDictionary *)getNodeInfo:(xmlNode *)node {
NSMutableDictionary *itemDict = [[[NSMutableDictionary alloc] initWithCapacity:1] autorelease];
xmlChar *value = NULL;
xmlAttr *attribute = NULL;
if (node && node->name && ![[NSString stringWithCString:(char *)node->name encoding:NSUTF8StringEncoding] isEqualToString:@"text"]) {
/* имя объекта */
value = (xmlChar*)node->name;
[itemDict setObject:[NSString stringWithCString:(char *)value encoding:NSUTF8StringEncoding] forKey:@"name"];
xmlFree(value);
/* атрибуты объекта */
attribute = node->properties;
NSMutableDictionary *attrDict = [[NSMutableDictionary alloc] initWithCapacity:1];
while(attribute && attribute->name && attribute->children)
{
value = xmlNodeListGetString(node->doc, attribute->children, 1);
[attrDict setObject:[NSString stringWithCString:(char *)value encoding:NSUTF8StringEncoding]
forKey:[NSString stringWithCString:(char *)attribute->name encoding:NSUTF8StringEncoding]];
xmlFree(value);
attribute = attribute->next;
}
[itemDict setObject:attrDict forKey:@"attr"];
[attrDict release];
/* значение объекта */
value = xmlNodeGetContent(node);
[itemDict setObject:[NSString stringWithCString:(char*)value encoding:NSUTF8StringEncoding] forKey:@"value"];
xmlFree(value);
/* дочерние объекты */
NSMutableArray *childArray = [[NSMutableArray alloc] initWithCapacity:1];
xmlNode *child = NULL;
for (child = node->children; child != NULL; child = child->next)
{
NSDictionary *childDict = [self getNodeInfo:child];
if ([childDict count]) {
[childArray addObject:childDict];
}
}
xmlFree(child);
if ([childArray count])
[itemDict setObject:childArray forKey:@"child"];
[childArray release];
}
return (NSDictionary *)itemDict;
}
There is a problem, libxml gives insignificant faces, most likely the faces of the library itself.