Database Reference
In-Depth Information
The interesting bit, from an XML parsing perspective, is what happens inside the
gotWeather method when the request succeeds. After doing the normal checks for bad
status codes, it uses the initWithXMLString method of the DDXMLDocument class to parse
the returned string into an XML DOM structure. The method takes a pointer to an
NSError object as an argument, and that is what you should check after the call to see
if the parse was successful.
Assuming the parse succeeded, the next step is to use the nodesForXPath method on the
returned XML document, specifying //data/time-layout as the XPath to look for. This
method returns an array of DDXMLElement objects, or nil if nothing matched the XPath
specified. The weather XML we get back follows a pattern I find particularly obnoxious
in XML DTDs: it makes you match up data from one part of the payload with data
from another part. In this case, the time-layout elements have to be matched up with
the attributes in the temperature elements, so we iterate over the time-layout elements,
building a dictionary of the layout names to the dates they represent.
I find when working with KissXML that I frequently want to get the string value of a
child node that I know only has a single instance. So I usually write a helper method
such as the getSingleStringValue method used in this example. Using it, I can snatch
the keys and start dates, and populate the dictionary with them. This method is shown
in Example 4-6 .
Example 4-6. The getSingleStringValue method
-(id) getSingleStringValue:(DDXMLElement *) element
xpath:(NSString *) xpath {
NSError *error = nil;
NSArray *vals = [element nodesForXPath:xpath error:&error];
if (error != nil) {
return nil;
}
if ([vals count] != 1) {
return nil;
}
DDXMLElement *val = [vals objectAtIndex:0];
return [val stringValue];
}
Basically, the method takes the root element for the extraction, and a relative or absolute
XPath expressing as a string. It gets the array of matching elements, makes sure there
wasn't an error (such as an invalid XPath string), and if it gets back exactly one element
in the array, returns it.
Once I have the dictionary, I iterate over the temperature data, grabbing attributes and
element values as appropriate, then use the diction to find the time associated with the
reading. Finally, I dump the data out to the log, resulting in this kind of output:
 
Search WWH ::




Custom Search