Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone NSXMLParser遇到特殊字符后停止解析_Iphone_Ios_Xml_Xcode_Xcode4 - Fatal编程技术网

Iphone NSXMLParser遇到特殊字符后停止解析

Iphone NSXMLParser遇到特殊字符后停止解析,iphone,ios,xml,xcode,xcode4,Iphone,Ios,Xml,Xcode,Xcode4,我正在从google weather 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

我正在从google weather 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获得的输出

XML Parser 1 ... elementName ... xml_api_reply
XML Parser 1 ... elementName ... weather
XML Parser 1 ... elementName ... forecast_information
问题是,它解析所有标记,直到到达“城市数据”,因为巴黎,法国巴黎的名称中有一个非ascii字符,然后它就停止了。它不会像邮政编码那样处理标签。纬度、经度等


所以我的问题是,有没有办法从返回的URL XML字符串中删除所有非ascii字符?

坚持使用ISO-8859-1,这样就不需要“删除特殊字符”。使用不同的机制获取http数据

使用NSURLConnection,它在长期运行和异步操作中要灵活得多

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

你所遇到的问题是,谷歌的回应使用了与你所期望的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-1,你会发现它也被称为拉丁字符集。内置编码选项之一是
nsisolatin1stringecoding
,因此请执行以下操作:

NSString *XML = [NSString stringWithContentsOfURL:URL encoding:NSISOLatin1StringEncoding error:&error];
使用正确的编码将使NSString能够理解如何解释字符,并且您将获得可用的数据。或者,您可以修改请求以指定希望Google提供的字符编码。这可能更可取,这样您就不必尝试将您使用的编码与特定请求相匹配

Edit:到目前为止,我的答案主要是将响应作为可读字符串。不过,我发现您真正的问题是使用NSXMLParser进行解析。我认为你至少有两个选择:

  • 修改收到的XML,以包含字符编码。返回的XML是拉丁文1编码的,但XML标记只显示:
    。您可以将其修改为:
    。我不知道这是否能解决NSXMLParser的问题,但它可能会

  • 如上所述,从谷歌请求您想要的字符集。将
    Accept字符集
    头添加到请求中应该可以做到这一点,不过这会使检索数据变得更复杂一些


    • 好的。我已经解决了这个问题。我就是这样让它工作的

      首先,我要做的是从带有特殊字符的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];
      
      NSString*地址=@”http://www.google.com/ig/api?weather=Paris";
      NSURL*URL=[NSURL URLWithString:address];
      n错误*错误;
      NSString*XML=[NSString stringWithContentsOfURL:URL编码:NSASCIIStringEncoding错误:&错误];
      //删除所有非ASCII字符
      NSMutableString*ascicharacters=[NSMutableString];
      对于(NSInteger i=32;i<127;i++)
      {
      [字符格式:@“%c”,i];
      }
      NSCharacterSet*非SCIAICharacterSet=[[NSCharacterSet characterSetWithCharactersInString:asciiCharacters]InversedSet];
      XML=[[XML组件由字符分隔集:非SCHIICharacterSet]组件由字符串连接:@”“];
      NSData*data=[XML数据使用编码:NSUTF8StringEncoding];
      NSXMLParser*parser=[[NSXMLParser alloc]initWithData:data];
      [解析器setDelegate:self];
      [语法分析器解析];
      
      编辑:


      NSXMLParser是一个可怕的工具。我已经在我的所有应用程序中成功地使用了RaptureXML。它超级容易使用,避免了所有这些非ascii字符的非意义

      我知道会发生什么,我也有同样的问题

      在解析器中查看
      foundCharacters
      方法

      我有这样的想法:

      if (!currentElementValue) {
         currentElementValue = [[NSMutableString alloc] initWithString:string];
      }
      
      当发生特殊字符时,
      currentElementValue
      刚刚停止获取

      现在我的工作代码是:

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

      请记住在
      didEndElement
      方法的末尾将
      currentElementValue
      设置为
      nil
      ,此对象没有为您做任何事情:
      NSString*XML=[NSString stringWithContentsOfURL:URL编码:NSASCIIStringEncoding错误:&error]您似乎根本没有使用它。
      NSXMLParser
      直接从
      URL
      加载。您是否收到解析或验证错误?@Justin-您是对的,因为我正在将URL传递给XML解析器,所以操作XML字符串不会做任何事。有没有一种方法可以在-(void)解析器中修改xml的结果?To:Jesse-我没有收到任何错误,发生的是XML在命中第一个特殊字符后停止解析。我有更多的标签,一旦你收到了数据,它们就不会被读取,但是,你仍然需要将其解释为文本,这意味着你必须使用正确的编码。返回的数据不是UTF8,因此试图以这种方式解释它是不正确的。你关于使用NSURLConnection来避免阻塞的观点很好,但是OP可能是在后台线程上发出此请求,在后台线程中,同步调用并不是一件坏事,而且对于单行请求的简单性,肯定有一些话要说。谢谢Caleb-我稍微改变了我的问题。问题就在这里。NSXMLParser*parser=[[NSXMLParser alloc]initwithcontentsofull:URL];在-(void)解析器中:。。。如何修复返回的URL结果中的特殊字符?如果需要特殊字符怎么办?这里的“currentElementValue”是什么
      if (!currentElementValue) {
          currentElementValue = [[NSMutableString alloc] initWithString:string];
      } else {
          [currentElementValue appendString:string];
      }