之前项目中用ios自带的XMLParser,实现了自适应解析(即 不管xml文档具体的值,解析成字典),但是因为本身XMLParser是异步的,可能有时候需要用同步时不方便。
正好 这两天用到 GDataXML, 发现如果对应对应的xml文件 做硬解析,可能之后文档发生变化又得重新编码了。于是编写了能自适应大部分的xml文档的 解析方法。当然具体解析需要什么类型看自己实际使用情况了。这里 是解析成字典的。
例如:
例 1:
<?xml version="1.0"encoding="utf-8"?>
<CMD_RES code=14 index=14 res = 0>
</CMD_RES>
解析为:
"CMD_RES" =
{
code = 14;
index = 14;
res = 0;
};
例2
<?xml version="1.0" encoding="utf-8"?>
<CMD_RES code="7" index="7" res = "0">
<AP index = "1" ssid = "aaaa" />
<AP index = "2" ssid = "bbbb" />
</CMD_RES>";
解析为:
"CMD_RES" = {
code = 7;
index = 7;
res = 0;
};
AP = (
{
index = 1;
ssid = "aaaa";
},
{
index = 2;
ssid = "bbbb";
},
);
代码本身不是很复杂,不过很方便,除了将根节点的,属性单独提出来,其他的属性都会和值一起包含在一起,试用的格式还是蛮多的,当然没有匹配所有的,因为才写好,有遗漏的可再修改部分细节。接下来把方法贴上,仅供参考,如果有更好的方法期待分享: )
@class GDataXMLDocument;
@interface XMLFileParser : NSObject
{
GDataXMLDocument *_xmlDoc;
}
- (NSDictionary *)getSyncXMLParserWithStr:(NSString *)xmlStr;
- (NSDictionary *)getSyncXMLParserWithData:(NSData *)xmlData;
@end
#import "GDataXMLNode.h"
@implementation XMLFileParser
#pragma mark -
#pragma mark Synchronous
- (NSDictionary *)getSyncXMLParserWithStr:(NSString *)xmlStr
{
if (nil == xmlStr)
{
return nil;
}
[_xmlDoc release];
_xmlDoc = [[GDataXMLDocumentalloc]initWithXMLString:xmlStroptions:0error:nil];
GDataXMLElement *rootElement = [_xmlDocrootElement];
return [selfxmlParser:rootElementifRootNode:YES];
}
- (NSDictionary *)getSyncXMLParserWithData:(NSData *)xmlData
{
if (nil == xmlData)
{
return nil;
}
[_xmlDoc release];
_xmlDoc = [[GDataXMLDocumentalloc]initWithData:xmlDataoptions:0error:nil];
GDataXMLElement *rootElement = [_xmlDocrootElement];
return [selfxmlParser:rootElementifRootNode:YES];
}
- (NSDictionary *)xmlParser:(GDataXMLElement *)element ifRootNode:(BOOL)isRoot
{
if (nil == element)
{
return nil;
}
NSMutableDictionary *dict = [NSMutableDictionarydictionary];
NSArray *attributes = [elementattributes];
NSMutableDictionary *headDict = [NSMutableDictionarydictionary];
for (GDataXMLElement *tempNodein attributes)
{
NSString *str = [tempNodename];
[headDict setObject:[tempNodestringValue]forKey:str];
}
if (isRoot)
{
//根节点的属性单独提出 类似例子中的 cmd_res
[dict setObject:headDictforKey:[elementname]];
}
else
{
[dict addEntriesFromDictionary:headDict];
}
for (GDataXMLElement *nodein [elementchildren])
{
NSString *nodeName = [nodename];
id nodeValue = [nodestringValue];
if ([node isKindOfClass:[GDataXMLElement class]] && [[node attributes] count] > 0)
{
nodeValue = [selfxmlParser:nodeifRootNode:NO];
}
else if ([node childCount] >1)
{
nodeValue = [selfxmlParser:nodeifRootNode:NO];
}
if ([dictobjectForKey:nodeName])
{
id sub = [dictobjectForKey:nodeName];
NSMutableArray *tempArray = [NSMutableArrayarray];
if ([subisKindOfClass:[NSArrayclass]] || [subisKindOfClass:[NSMutableArrayclass]])
{
[tempArray addObjectsFromArray:sub];
}
else
{
[tempArray addObject:sub];
}
[tempArray addObject:nodeValue];
[dict setObject:tempArrayforKey:nodeName];
}
else
{
[dict setObject:nodeValueforKey:nodeName];
}
}
return dict;
}
- (void)dealloc
{
[_xmlDoc release];
[super dealloc];
}
@end
//初次试用GDataXML,写了自动解析的方法,暂时没考虑效率问题,代码供参考,若有优化或者更好的方法欢迎指出:)