我读从谷歌API的天气一个XML文件,并使用的NSXMLParser解析它。 有问题的城市是巴黎。 下面是一个简单的XML输出我得到
<?xml version="1.0"?>
<xml_api_reply version="1">
<weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1" row="0" section="0" ><forecast_information>
<city data="Paris, Île-de-France"/>
<postal_code data="Paris"/>
<latitude_e6 data=""/>
<longitude_e6 data=""/>
...
...
现在的代码我用来剥此XML
NSString *address = @"http://www.google.com/ig/api?weather=Paris";
NSURL *URL = [NSURL URLWithString:address];
NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:URL];
[parser setDelegate:self];
[parser parse];
...
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
NSLog(@"XML Parser 1 ... elementName ... %@", elementName);
}
这是输出,我得到了上面的XML
XML Parser 1 ... elementName ... xml_api_reply
XML Parser 1 ... elementName ... weather
XML Parser 1 ... elementName ... forecast_information
问题是,它分析所有的标签,直到它达到“城市数据”因为是在巴黎的名字,法兰西岛非ASCII字符,然后它只是停止。 它不处理的标签之后像POSTAL_CODE。 纬度,经度等。
所以我的问题是,有没有方法可以让我从返回的URL XML字符串中删除所有非ASCII字符?
我知道可能会发生,我刚有同样的问题...
看看你foundCharacters
方法在你的分析器...
我有这样的事情:
if (!currentElementValue) {
currentElementValue = [[NSMutableString alloc] initWithString:string];
}
和currentElementValue
刚刚停止时得到特殊字符happend。
现在我的工作代码为:
if (!currentElementValue) {
currentElementValue = [[NSMutableString alloc] initWithString:string];
} else {
[currentElementValue appendString:string];
}
记得设置currentElementValue
到nil
在你结束didEndElement
方法
好。 我已经解决了这个问题。 这是我得到它的工作。
首先,我做的就是从特殊字符的URL中的XML。 然后,我带出从XML字符串的所有特殊字符。 然后,我转换字符串的NSData,然后传递NSData对象我的NSXMLParser。 因为它没有更多的特殊字符的NSXMLParser是幸福的。
这里是谁可能在将来的运行跨任何人的代码。 非常感谢大家谁到这个职位功不可没!
NSString *address = @"http://www.google.com/ig/api?weather=Paris";
NSURL *URL = [NSURL URLWithString:address];
NSError *error;
NSString *XML = [NSString stringWithContentsOfURL:URL encoding:NSASCIIStringEncoding error:&error];
//REMOVE ALL NON-ASCII CHARACTERS
NSMutableString *asciiCharacters = [NSMutableString string];
for (NSInteger i = 32; i < 127; i++)
{
[asciiCharacters appendFormat:@"%c", i];
}
NSCharacterSet *nonAsciiCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:asciiCharacters] invertedSet];
XML = [[XML componentsSeparatedByCharactersInSet:nonAsciiCharacterSet] componentsJoinedByString:@""];
NSData *data = [XML dataUsingEncoding:NSUTF8StringEncoding];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
[parser setDelegate:self];
[parser parse];
编辑:
的NSXMLParser是一个可怕的工具。 我已经成功地使用RaptureXML在我所有的应用程序。 它的超级好用,并且避免非ASCII字符的这一切无感。 https://github.com/ZaBlanc/RaptureXML
您遇到的问题是,谷歌的反应使用不同的编码比你期待的ASCII或UTF8。 使用便捷的命令行工具curl
,很容易看出:
$ curl -I http://www.google.com/ig/api?weather=Paris
HTTP/1.1 200 OK
X-Frame-Options: SAMEORIGIN
Content-Type: text/xml; charset=ISO-8859-1
...
如果你看到了ISO-8859,你会发现,它也被称为Latin-1的字符集。 其中一个内置的编码选项是NSISOLatin1StringEncoding
,所以这样做:
NSString *XML = [NSString stringWithContentsOfURL:URL encoding:NSISOLatin1StringEncoding error:&error];
使用正确的编码将有可能使的NSString弄清楚如何解释字符,你会得到有用的数据。 或者,您可以修改您的要求指定您希望谷歌提供的字符编码。 这可能是可取的,这样你就不必尝试匹配您使用的具体要求的编码。
编辑:到现在为止,我的回答对论点集中刚开响应为可读的字符串。 我看你是真正的问题涉及到用的NSXMLParser解析,虽然。 我认为你至少有两个选项:
修改您收到包含的字符编码的XML。 那你得到的XML是Latin-1的编码,但XML标签只是说: <?xml version="1.0"?>
。 你可以修改的样子: <?xml version="1.0" encoding="ISO-8859-1"?>
。 我不知道这是否会解决的NSXMLParser的问题,但它可能。
如上文建议, 请您从谷歌想要的字符集 。 添加一个Accept-Charset
报头请求应该做的伎俩,虽然这会让检索数据稍微复杂一点。
与ISO-8859-1坚持,所以你并不需要“去除特殊字符”。 使用不同的机制以获取的HTTP数据。
使用一个NSURLConnection的,它远远的长远和asynchronos更加灵活。
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:15.0];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
// Create the NSMutableData to hold the received data.
// receivedData is an instance variable declared elsewhere.
receivedData = [[NSMutableData data] init];
return YES;
} else {
// Inform the user that the connection failed.
return NO;
}
}
#pragma mark - Url connection data delegate
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[receivedData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
receivedData = nil;
[self badLoad];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
//inform delegate of completion
[self.delegate fetchedData:receivedData];
receivedData = nil;
}