简体   繁体   中英

iPhone XMLParser help

I am needing to parse an XML file for my app and I dont have any clue how to do it. I went through one XMLParser tutorial, and it worked fine but the XML file in the tutorial was very simple and my XML file is quite a bit more complex.

here is a snippet of the xml file:

  <?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>

What I'm needing to do is search the XML file for the <...icao_ident> that the user specifies, then create a dictionary containing the <pdf_name> and <chart_name> for each <record> . I will then create a UI that displays the pdf files.

Can someone direct me to a good tutorial or explanation of how XML parser works? Or if I'm going about this the wrong way I'd be open to suggestions too.

(the XML file is about 8MB)

You might find that my blog post about wrapping NSXMLParser gives you what you need - and possibly a higher level alternative (my wrapper).

For example, using my technique, you'd write methods like:

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

I suggest you to read the Event-Driven XML Programming Guide for Cocoa . In your specific case, what you need to do is:

  • In the parser:didStartElement: check for the element name: "airport_name", initialize a new array to store all the record elements (or you can define your own data structure to store the record element), a dictionary to store all element in the record, one string variable to store the current text
  • In the parser:foundCharacters: append the string to the current text
  • In the parser:didEndElement: save the dictionary to the array, release the array, save the results.

UPDATED

- (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 ...
}}

i know this isn't the best way...

I struggled for 2 days trying to adapt the XML parser to my situation. I couldnt grasp it, probably because I'm just so used to doing this in C# and obj-c is new to me...

So what I did was parsed the whole thing as a string.

I converted the entire XML file to a NSString, then used substringToIndex and substringFromIndex to isolate the section I needed (the airport). I then used the </record> tag to create an array of <records> , then wrote a for loop that took the values I needed out of the each array object just by getting the range of the tags.

Like I said, it was a crazy solution, but I did it all in 26 lines of code and it works great.

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];


}

followed by cleanup...

The default XML parsing on the iPhone is pretty tragic compared with contemporary scripting languages. If you are doing serious parsing with complex objects with multiple levels of child objects, then god help you with NSXMLParser.

I would recommend checking out TouchXML which offers a much more civilized solution that is closer to what you might see in a language like Python or Actionscript in terms of its implementation within your own source.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM