NSXMLParser 和 Geonames

发布于 2024-09-03 17:11:33 字数 11768 浏览 8 评论 0原文

我正在尝试使用 iPhone SDK 中的 NSXMLParser 解析来自 Geonames 的调用。我以前用过这个,但由于某种原因,即使我在网络浏览器中得到结果,我也得到了一个空字典。有人可以指出我可能做错了什么吗?

下面是我正在使用的代码以及将其粘贴到浏览器中返回的结果。

预先感谢

 #pragma mark -
#pragma mark - Parcer Services

-(void)beginLoadingFeed{
 //[self startLoadingWithMessage:@"Loading Results...."]; 
 NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadFeed) object:nil];
 [operationQueue addOperation:operation];
 [operation release];
}

- (void)loadFeed{
 NSString *path = [NSString stringWithFormat:@"http://ws.geonames.org/postalCodeSearch?placename=%@&long&maxRows=20",self.location];
 [Logger log:@"Geonames Query: %@",path];
 [self parseXMLFileAtURL:path]; 
 [self performSelectorOnMainThread:@selector(didfinishedLoadingFeed) withObject:nil waitUntilDone:YES];
}

-(void)didfinishedLoadingFeed{

}

- (void)parserDidStartDocument:(NSXMLParser *)parser{ 
 [Logger log:@"found file and started parsing"]; 
}


//Called when the parser runs into an open tag (<tag>)
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {

 if ([elementName isEqualToString:@"code"]) {
  currentResult = [NSMutableDictionary dictionary]; 
 } else {
  currentElement = [elementName copy];
 }

}

//This is just to resolve random HTML entities
- (NSData *)parser:(NSXMLParser *)parser resolveExternalEntityName:(NSString *)entityName systemID:(NSString *)systemID {
 return [entityName dataUsingEncoding:NSASCIIStringEncoding];
} 


- (void)parseXMLFileAtURL:(NSString *)URL{ 
 self.results = [[[NSMutableArray alloc] init] autorelease];
 NSURL *xmlURL = [NSURL URLWithString:URL];
 NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
 [parser setDelegate:self];
 [parser parse];
 [parser autorelease];
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
 NSString * errorString = [NSString stringWithFormat:@"Unable to connect to web site (Error code %i )", [parseError code]];
 [Logger log:@"error parsing : %@", errorString]; 
 [self stopLoadingView];
 [self showMessage:@"Error loading content" withTitle:@"Error Loading"];
}



/*** Called when the parser runs into a close tag (</tag>). If it is the Result tag that is closing, we should add the currentResult to the array, and then forget about it ***/
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
 if ([elementName isEqualToString:@"code"]) {
   [self.results addObject:currentResult];
   currentResult = nil;
 }
}


- (void)parserDidEndDocument:(NSXMLParser *)parser {
 [Logger log:@"all done!"]; 
 [Logger log:@"results array has %d items", [self.results count]];
 [Logger log:@"Results:%@",results];
 [theTableView reloadData];
 [self stopLoadingView];
}

以下是在搜索术语“波士顿”时使用上面相同的调用在浏览器中返回的结果:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<geonames>
<totalResultsCount>2808</totalResultsCount>
<code>
<postalcode>02101</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.370567</lat>
<lng>-71.026964</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02108</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.357603</lat>
<lng>-71.068432</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02109</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.360027</lat>
<lng>-71.054495</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02110</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.357636</lat>
<lng>-71.051417</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02111</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.350348</lat>
<lng>-71.0629</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02114</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.361111</lat>
<lng>-71.06823</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02115</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.342706</lat>
<lng>-71.092215</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02116</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.349201</lat>
<lng>-71.076798</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02118</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.336162</lat>
<lng>-71.072854</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02128</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.364197</lat>
<lng>-71.025694</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02199</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.347873</lat>
<lng>-71.082543</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02210</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.348921</lat>
<lng>-71.046511</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02215</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.347088</lat>
<lng>-71.102689</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>22713</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>38.538241</lat>
<lng>-78.142285</lng>
<adminCode1>VA</adminCode1>
<adminName1>Virginia</adminName1>
<adminCode2>047</adminCode2>
<adminName2>Culpeper</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>24592</postalcode>
<name>South Boston</name>
<countryCode>US</countryCode>
<lat>36.696335</lat>
<lng>-78.918829</lng>
<adminCode1>VA</adminCode1>
<adminName1>Virginia</adminName1>
<adminCode2>083</adminCode2>
<adminName2>Halifax</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02102</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.338947</lat>
<lng>-70.919635</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02103</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.338947</lat>
<lng>-70.919635</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02104</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.338947</lat>
<lng>-70.919635</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02105</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.338947</lat>
<lng>-70.919635</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02106</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.354318</lat>
<lng>-71.073449</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
</geonames>

I'm trying to parse a call from Geonames with NSXMLParser in the iPhone SDK. I've used this before but for some reason I'm getting an empty dictionary back even though I get results back in a web browser. Can someone please point out what I may be doing wrong.

Below is the code I'm using and the results that comes back pasting it in a browser.

Thanks in advance

 #pragma mark -
#pragma mark - Parcer Services

-(void)beginLoadingFeed{
 //[self startLoadingWithMessage:@"Loading Results...."]; 
 NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadFeed) object:nil];
 [operationQueue addOperation:operation];
 [operation release];
}

- (void)loadFeed{
 NSString *path = [NSString stringWithFormat:@"http://ws.geonames.org/postalCodeSearch?placename=%@&long&maxRows=20",self.location];
 [Logger log:@"Geonames Query: %@",path];
 [self parseXMLFileAtURL:path]; 
 [self performSelectorOnMainThread:@selector(didfinishedLoadingFeed) withObject:nil waitUntilDone:YES];
}

-(void)didfinishedLoadingFeed{

}

- (void)parserDidStartDocument:(NSXMLParser *)parser{ 
 [Logger log:@"found file and started parsing"]; 
}


//Called when the parser runs into an open tag (<tag>)
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {

 if ([elementName isEqualToString:@"code"]) {
  currentResult = [NSMutableDictionary dictionary]; 
 } else {
  currentElement = [elementName copy];
 }

}

//This is just to resolve random HTML entities
- (NSData *)parser:(NSXMLParser *)parser resolveExternalEntityName:(NSString *)entityName systemID:(NSString *)systemID {
 return [entityName dataUsingEncoding:NSASCIIStringEncoding];
} 


- (void)parseXMLFileAtURL:(NSString *)URL{ 
 self.results = [[[NSMutableArray alloc] init] autorelease];
 NSURL *xmlURL = [NSURL URLWithString:URL];
 NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
 [parser setDelegate:self];
 [parser parse];
 [parser autorelease];
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
 NSString * errorString = [NSString stringWithFormat:@"Unable to connect to web site (Error code %i )", [parseError code]];
 [Logger log:@"error parsing : %@", errorString]; 
 [self stopLoadingView];
 [self showMessage:@"Error loading content" withTitle:@"Error Loading"];
}



/*** Called when the parser runs into a close tag (</tag>). If it is the Result tag that is closing, we should add the currentResult to the array, and then forget about it ***/
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
 if ([elementName isEqualToString:@"code"]) {
   [self.results addObject:currentResult];
   currentResult = nil;
 }
}


- (void)parserDidEndDocument:(NSXMLParser *)parser {
 [Logger log:@"all done!"]; 
 [Logger log:@"results array has %d items", [self.results count]];
 [Logger log:@"Results:%@",results];
 [theTableView reloadData];
 [self stopLoadingView];
}

Below is the result that comes back in a browser using the same call above when doing the search for the term "boston":

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<geonames>
<totalResultsCount>2808</totalResultsCount>
<code>
<postalcode>02101</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.370567</lat>
<lng>-71.026964</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02108</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.357603</lat>
<lng>-71.068432</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02109</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.360027</lat>
<lng>-71.054495</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02110</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.357636</lat>
<lng>-71.051417</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02111</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.350348</lat>
<lng>-71.0629</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02114</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.361111</lat>
<lng>-71.06823</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02115</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.342706</lat>
<lng>-71.092215</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02116</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.349201</lat>
<lng>-71.076798</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02118</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.336162</lat>
<lng>-71.072854</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02128</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.364197</lat>
<lng>-71.025694</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02199</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.347873</lat>
<lng>-71.082543</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02210</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.348921</lat>
<lng>-71.046511</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02215</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.347088</lat>
<lng>-71.102689</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>22713</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>38.538241</lat>
<lng>-78.142285</lng>
<adminCode1>VA</adminCode1>
<adminName1>Virginia</adminName1>
<adminCode2>047</adminCode2>
<adminName2>Culpeper</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>24592</postalcode>
<name>South Boston</name>
<countryCode>US</countryCode>
<lat>36.696335</lat>
<lng>-78.918829</lng>
<adminCode1>VA</adminCode1>
<adminName1>Virginia</adminName1>
<adminCode2>083</adminCode2>
<adminName2>Halifax</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02102</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.338947</lat>
<lng>-70.919635</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02103</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.338947</lat>
<lng>-70.919635</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02104</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.338947</lat>
<lng>-70.919635</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02105</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.338947</lat>
<lng>-70.919635</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
<code>
<postalcode>02106</postalcode>
<name>Boston</name>
<countryCode>US</countryCode>
<lat>42.354318</lat>
<lng>-71.073449</lng>
<adminCode1>MA</adminCode1>
<adminName1>Massachusetts</adminName1>
<adminCode2>025</adminCode2>
<adminName2>Suffolk</adminName2>
<adminCode3/>
<adminName3/>
</code>
</geonames>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小伙你站住 2024-09-10 17:11:33

您将得到一个空字典,因为 currentResult 从未给出任何数据。 didStartElementdidEndElement 方法实际上并没有提供 bar 标记内的内容。

要获取元素的实际内容,请使用 - (void)parser:(NSXMLParser *)parserfoundCharacters:(NSString *)string 方法。

You're getting a null dictionary because currentResult is never given any data. The didStartElement and didEndElement methods don't actually give you what's inside the <foo>bar</foo> tag.

To get the actual content of an element, use the - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文