iPhone XMLParser帮助
我需要解析我的应用程序的XML文件,我没有任何线索如何做到这一点。我经历了一个XMLParser教程,它运行良好,但教程中的XML文件非常简单,我的XML文件比较复杂。iPhone XMLParser帮助
这里是xml文件的一个片段:
<?xml version="1.0" encoding="UTF-8"?>
<digital_tpp cycle="1003" from_edate="0901Z 03/11/10" to_edate="0901Z 04/08/10">
<state_code ID="AK" state_fullname="Alaska">
<city_name ID="ADAK ISLAND" volume="AK-1">
<airport_name ID="ADAK" military="N" apt_ident="ADK" icao_ident="PADK" alnum="1244">
<record>
<chartseq>10100</chartseq>
<chart_code>MIN</chart_code>
<chart_name>TAKE-OFF MINIMUMS</chart_name>
<useraction></useraction>
<pdf_name>AKTO.PDF</pdf_name>
<cn_flg>N</cn_flg>
<cnsection></cnsection>
<cnpage></cnpage>
<bvsection>C</bvsection>
<bvpage></bvpage>
<procuid></procuid>
<two_colored>N</two_colored>
<civil> </civil>
<faanfd15></faanfd15>
<faanfd18></faanfd18>
<copter></copter>
</record>
<record>
<chartseq>10200</chartseq>
<chart_code>MIN</chart_code>
<chart_name>ALTERNATE MINIMUMS</chart_name>
<useraction></useraction>
<pdf_name>AKALT.PDF</pdf_name>
<cn_flg>N</cn_flg>
<cnsection></cnsection>
<cnpage></cnpage>
<bvsection>E</bvsection>
<bvpage></bvpage>
<procuid></procuid>
<two_colored>N</two_colored>
<civil> </civil>
<faanfd15></faanfd15>
<faanfd18></faanfd18>
<copter></copter>
</record>
</airport_name>
</city_name>
</state_code>
</digital_tpp>
什么,我需要做的是搜索与用户指定的<...icao_ident>
XML文件,然后创建一个包含了<pdf_name>
和<chart_name>
字典每个<record>
。然后,我将创建一个显示PDF文件的UI。
有人可以指导我一个很好的教程或XML解析器如何工作的解释吗?或者,如果我以这种错误的方式开展工作,我也会接受建议。
(XML文件约8MB)
我知道这是不是最好的办法...
我奋斗2天努力使XML解析器适应我的情况。我不能理解它,可能是因为我只是习惯于在C#中做这件事,obj-c对我来说是新的...
所以我所做的就是将整个事情解析为一个字符串。
我将整个XML文件转换为NSString,然后使用substringToIndex和substringFromIndex来隔离我需要的部分(机场)。然后,我使用</record>
标签创建了一个<records>
的数组,然后编写了一个for循环,通过获取标签的范围,从每个数组对象中提取所需的值。
就像我说的那样,这是一个疯狂的解决方案,但是我在26行代码中完成了所有工作,并且效果很好。
NSString *path = [[NSBundle mainBundle] pathForResource:@"dttps" ofType:@"xml"];
NSData *data = [[NSData alloc]initWithContentsOfFile:path];
NSString *xmlString = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSRange range = [xmlString rangeOfString:searchedAirport];
xmlString = [xmlString substringFromIndex:range.location];
range = [xmlString rangeOfString:@"/airport_name"];
xmlString = [xmlString substringToIndex:range.location];
NSMutableArray *chartNames = [[NSMutableArray alloc]initWithCapacity:100] ;
NSMutableArray *pdfNames = [[NSMutableArray alloc]initWithCapacity:100] ;
NSArray *charts = [xmlString componentsSeparatedByString:@"</record>"];
NSString *tempString = [[NSString alloc]initWithFormat:@""];
int chartsCount = [charts count]-1;
int x;
for (x=0; x < chartsCount; x=x+1) {
tempString = [charts objectAtIndex:x];
range = [tempString rangeOfString:@"<chart_name>"];
tempString = [tempString substringFromIndex:range.location+12];
range = [tempString rangeOfString:@"</chart_name>"];
tempString = [tempString substringToIndex:range.location];
[chartNames addObject:tempString];
tempString = [charts objectAtIndex:x];
range = [tempString rangeOfString:@"<pdf_name>"];
tempString = [tempString substringFromIndex:range.location+10];
range = [tempString rangeOfString:@"</pdf_name>"];
tempString = [tempString substringToIndex:range.location-4];
[pdfNames addObject:tempString];
}
随后清理...
我建议你阅读Event-Driven XML Programming Guide for Cocoa。在特定情况下,你需要做的是:
- 在解析器:didStartElement:检查元素名称:“AIRPORT_NAME”,初始化一个新的阵列来存储所有的记录元素(或者你也可以定义自己的数据结构来存储该记录元件),词典存储在所述记录中的所有元件,一个字符串变量来存储当前的文本
- 在解析器:foundCharacters:字符串附加到当前文本
- 在解析器:didEndElement:将字典保存到数组,释放数组,保存结果。
修订
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
if ([elementName isEqualToString:@"airport_name"]) {
if (!airports)
airports = [[NSMutableArray alloc] init];
NSString *str_icao_ident = [attributeDict objectForKey:@"icao_ident"];
//do something
return;
// ... continued ...
}}
你可能会发现,my blog post about wrapping NSXMLParser
为您提供您所需要的 - 和可能更高水平的替代(我的包装)。
例如,使用我的技术,你会写这样的方法:
-(void) handleElement_chartname: (NSDictionary*) attributes;
该死的对那些if语句来说是一个很好的解决方案(除了下划线,但这是一个偏好的事情)。刚好足够的元编程以避免恼人的if-else块。太好了!它仍然是一个连续的解析器,但由于某种原因,我们忍受了在其他平台上我们在DECADES中无法忍受的iOS上的事情,但我认为创建一个类似DOM的解析器是很容易的(并且全部弄错了)。 – 2011-01-11 20:33:00
与当代脚本语言相比,iPhone上默认的XML解析非常悲惨。如果您正在使用具有多级子对象的复杂对象进行严重解析,那么上帝可以帮助您使用NSXMLParser。
我会推荐检查一下TouchXML,它提供了一个更加文明的解决方案,它更接近您可能在Python或Actionscript语言中看到的在您的源代码中实现的方面。
我会看看那个。我认为这是我的问题的一部分,它是一个非常复杂的XML文件。没有什么比我在我尝试的教程中找到的示例xml文件。 – Brodie 2010-04-21 04:31:25
我该如何在airport_name元素中找到正确的icao_ident属性? – Brodie 2010-04-20 01:44:16
我编辑了答案,告诉我你是否需要更多帮助 – 2010-04-20 08:56:58
谢谢hoang - 我今晚会试试 – Brodie 2010-04-20 15:57:31