遇到的NSXMLParser特殊字符后停止解析(NSXMLParser stops parsing

2019-09-20 21:17发布

我读从谷歌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字符?

Answer 1:

我知道可能会发生,我刚有同样的问题...

看看你foundCharacters方法在你的分析器...

我有这样的事情:

if (!currentElementValue) {
   currentElementValue = [[NSMutableString alloc] initWithString:string];
}

currentElementValue刚刚停止时得到特殊字符happend。

现在我的工作代码为:

if (!currentElementValue) {
    currentElementValue = [[NSMutableString alloc] initWithString:string];
} else {
    [currentElementValue appendString:string];
}

记得设置currentElementValuenil在你结束didEndElement方法



Answer 2:

好。 我已经解决了这个问题。 这是我得到它的工作。

首先,我做的就是从特殊字符的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



Answer 3:

您遇到的问题是,谷歌的反应使用不同的编码比你期待的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报头请求应该做的伎俩,虽然这会让检索数据稍微复杂一点。



Answer 4:

与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;
}


文章来源: NSXMLParser stops parsing after encountering special character