XML parsing of iOS Network Data
When you request data from the server, the data must be stored in a specific format. Then, one Party organizes the data in this format, and the other party parses the data in the same way, it's like talking between us, our words will turn into vibration, spreading in the air, then the other's ears will feel this vibration, and then turn the vibration into words, therefore, I think the format organization is to better transmit data. Generally, network data is encapsulated in two formats for transmission: XML and json.
1. "resolution":
XML looks like HTML. Open the source code display function of the browser and you can see a string of <> tags. XML parsing also relies on these tags. First, let's talk about the "resolution" that I understand. XML or json is actually a large string. Parsing is to convert this string into a dictionary or array according to the XML or json format specifications, in this way, you can freely obtain the data in it. For example:
Clear to cloudy
Breeze
34 ~ 23 ℃
The weather label is "clear to cloudy", that is, the weather is clear to cloudy, so this is a key-value pair in the dictionary, weather is the key, and clear to cloudy is the value. XML, json, and array dictionaries are all about organizing data. "Parsing" means converting data from an organizational format to another one.2. DOM and SAX:
This is two ways to parse XML. DOM loads the entire XML document, and the data structure in this document is clear. Then, you can use XPath to directly obtain a node; while SAX reads down from the XML header one by TAG one by one. If you encounter something, you will be notified. Therefore, it does not need to be obtained from all the XML documents, but it can only get where it is currently read, I can't get what I have read before, so the structure is not very clear, but it is relatively fast and consumes little memory. I personally think DOM Parsing is more convenient.
3. Selection of resolution class libraries:
See article: Comparison of XML parsing class libraries on iOS platform
4. Use of NSXMLParser in the system:
XML data to use Baidu weather interface data, address: http://api.map.baidu.com/telematics/v3/weather? Location = % E5 % 8C % 97% E4 % BA % AC & ak = 5slgyqGDENN7Sy7pw29IUvrZ. For information about the weather interface configuration, refer to: Baidu weather Interface
(1) obtain data:
-(void )getXMLData{ NSString * URLStr = @"http://api.map.baidu.com/telematics/v3/weather?location=%E5%8C%97%E4%BA%AC&ak=5slgyqGDENN7Sy7pw29IUvrZ"; NSURL * url = [NSURL URLWithString:URLStr]; NSURLRequest * request = [[NSURLRequest alloc]initWithURL:url]; _XMLData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; }
(2) construct NSXMLParser:
-(void )parserXMLData{ _parser = [[NSXMLParser alloc]initWithData:_XMLData]; _parser.delegate = self; if (![_parser parse]) { NSLog(@"Parser start error"); }}
Here we use the NSData object to build, you can also use the document resource address to build-(id) initWithData :( NSData *) data, use the input stream to build:-(id) initWithStream :( NSInputStream *) stream. Call parse to enable resolution. You need to set the delegate object. In this way, when parsing an element change or character, the delegate object will call the delegate method, which is to process data in these methods.
(3) delegate method:-(Void) parserDidStartDocument :( NSXMLParser *) parser {// start parsing the document by calling NSLog (@ "doucment start");}-(void) parser :( NSXMLParser *) parser didStartElement :( NSString *) elementName namespaceURI :( NSString *) namespaceURI qualifiedName :( NSString *) qName attributes :( NSDictionary *) attributeDict {// each time a tag is parsed, for example
Clear to cloudy
In
Tag _ currentElement = elementName; // Save the current tag to facilitate the judgment of if ([_ currentElement is1_tostring: @ "weather_data"]) in the following method: {// construct an array when parsing the weather_data tag to save weather information for multiple days. _ WeatherArray = [[NSMutableArray alloc] init];} else if ([_ currentElement is1_tostring: @ "date"] & _ weatherArray) {// because the date tag changes the weather information of each day, a dictionary is constructed when the date tag is parsed to save the weather information of a day, and add it to the _ weatherArray using * oneDayWeather = [[NSMutableDictionary alloc] init]; [_ weatherArray addObject: oneDayWeather] ;}- (void) parser :( NSXMLParser *) parser foundCharacters :( NSString *) string {// each time it is parsed to a string, in the XML document, except the tag, it is the data, and the data contains several strings, therefore, this method is called when the string data is used. For example
Clear to cloudy
In the clear to cloudy. String = [string stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString: @ "\ n \ r"]; // remove spaces and line breaks through this method, ensure that useful strings are stored in if (_ weatherArray & string. length> 0) {if ([_ currentElement is1_tostring: @ "date"]) {// use the value of _ currentElement to determine which tag is in which NSMutableDictionary * oneDayWeather = _ weatherArray. lastObject; // lastObject is the latest dictionary, that is, the dictionary for storing data currently [oneDayWeather setObject: string forKey: @ "date"];} else if ([_ currentElement is1_tostring: @ "dayPictureUrl"]) {NSMutableDictionary * oneDayWeather = _ weatherArray. lastObject; [oneDayWeather setObject: string forKey: @ "dayPictureUrl"];} else if ([_ currentElement is1_tostring: @ "nightPictureUrl"]) {Region * oneDayWeather = _ weatherArray. lastObject; [oneDayWeather setObject: string forKey: @ "nightPictureUrl"];} else if ([_ currentElement is1_tostring: @ "weather"]) {optional * oneDayWeather = _ weatherArray. lastObject; [oneDayWeather setObject: string forKey: @ "weather"];} else if ([_ currentElement is1_tostring: @ "wind"]) {NSMutableDictionary * oneDayWeather = _ weatherArray. lastObject; [oneDayWeather setObject: string forKey: @ "wind"];} else if ([_ currentElement is1_tostring: @ "temperature"]) {NSMutableDictionary * oneDayWeather = _ weatherArray. lastObject; [oneDayWeather setObject: string forKey: @ "temperature"] ;}}- (void) parser :( NSXMLParser *) parser foundCDATA :( NSData *) CDATABlock {// similar to the above string, some data is not a string, but a byte. Here is the NSData object NSLog (@ "% @", [[NSString alloc] initWithData: CDATABlock encoding: NSUTF8StringEncoding]);}-(void) parser :( NSXMLParser *) parser didEndElement :( NSString *) elementName namespaceURI :( NSString *) namespaceURI qualifiedName :( NSString *) qName {// called when a tag is parsed to an end. Each tag is a pair of the beginning and end, for example
Clear to cloudy
In
And
, When resolved
Is the end of a tag, and this method will be called. // NSLog (@ "elementName: % @, namespaceURI: % @, qualifiedName: % @", elementName, namespaceURI, qName);}-(void) parserDidEndDocument :( NSXMLParser *) parser {// This is the NSLog (@ "document end"); NSLog (@ "% @", _ weatherArray );}
The above lists some delegate methods called during the parsing process, and many other methods. For details, refer to NSXMLParserDelegate in this document. It seems that the method is very detailed and every detail of the parsing process is taken into account. However, it is not easy to store the data in XML into an array dictionary. I don't want to use json, one sentence is enough. The biggest difference in SAX Parsing is that when a tag is parsed, you don't know what the tag on the previous layer is or what the tag on the upper layer is, that is to say, nothing can tell you the structure of the entire document. The preceding example shows how to extract the popular weather section of the XML document obtained in the link and put it in the array _ weatherArray, that is
...
Content in this label.In general, it is not very convenient to parse the data. If the data hierarchy is complicated, it will be very troublesome to process. Therefore, DOM parsing and json format should be considered.