iPhone XMLParser帮助

时间:2010-04-19 01:53:36

标签: iphone objective-c xml nsxmlparser

我需要解析我的应用程序的XML文件,我不知道如何做到这一点。我浏览了一个XMLParser教程,它运行良好,但教程中的XML文件非常简单,我的XML文件也相当复杂。

这是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>

我需要做的是在XML文件中搜索用户指定的<...icao_ident>,然后为每个{{1}创建一个包含<pdf_name><chart_name>的字典}。然后,我将创建一个显示pdf文件的UI。

有人可以指导我学习XML解析器的工作原理吗?或者,如果我以错误的方式解决这个问题,我也会接受建议。

(XML文件大约8MB)

4 个答案:

答案 0 :(得分:2)

您可能会发现my blog post about wrapping NSXMLParser为您提供了所需的内容 - 可能还有更高级别的替代方案(我的包装)。

例如,使用我的技术,您可以编写如下方法:

-(void) handleElement_chartname: (NSDictionary*) attributes;

答案 1 :(得分:1)

我建议你阅读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 ...
}}

答案 2 :(得分:1)

我知道这不是最好的方式......

我努力使XML解析器适应我的情况2天。我无法理解它,可能是因为我只是习惯于在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];


}

然后进行清理......

答案 3 :(得分:0)

与现代脚本语言相比,iPhone上的默认XML解析非常悲惨。如果您正在使用具有多个子对象级别的复杂对象进行严格的解析,那么上帝会帮助您使用NSXMLParser。

我建议查看TouchXML,它提供了一个更加文明的解决方案,它更接近你在Python或Actionscript等语言中看到的在你自己的源代码中的实现。