2

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 を解析するために使用したコードは次のとおりです。

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

問題は、名前 Paris, Île-de-France に非 ASCII 文字が含まれているため、「都市データ」に到達するまですべてのタグを解析し、その後停止することです。postal_code のように、後でタグを処理しません。緯度、経度など

私の質問は、返された URL XML 文字列から非 ASCII 文字をすべて削除する方法はありますか?

4

4 に答える 4

8

私は何が起こっているのか知っています、私はちょうど同じ問題を抱えていました...

パーサーでメソッドを見てくださいfoundCharacters...

私はこのようなものを持っていました:

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

currentElementValue特殊文字が発生したときに取得を停止しました。

今私の作業コードは次のとおりです。

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

メソッドの最後にcurrentElementValuetoを設定することを忘れないでくださいnildidEndElement

于 2012-11-01T18:25:30.920 に答える
2

Ok。私はこの問題を解決しました。これが私がそれを機能させる方法です。

まず、特殊文字を含む 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

于 2012-08-06T17:53:47.567 に答える
0

あなたが抱えている問題は、Google の応答が、期待している 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 を調べると、Latin-1 文字セットとしても知られていることがわかります。組み込みのエンコーディング オプションの 1 つが であるNSISOLatin1StringEncodingため、次のようにします。

NSString *XML = [NSString stringWithContentsOfURL:URL encoding:NSISOLatin1StringEncoding error:&error];

正しいエンコーディングを使用すると、NSString が文字を解釈する方法を理解できるようになり、使用可能なデータが返されます。または、リクエストを変更して、Google に提供してもらいたい文字エンコーディングを指定することもできます。使用するエンコーディングを特定のリクエストに一致させようとする必要がないように、それが望ましい場合があります。

編集:この時点まで、私の答えは、応答を読み取り可能な文字列として取得することに焦点を当てています。ただし、あなたの本当の質問には NSXMLParser での解析が含まれていることがわかります。ここには少なくとも 2 つのオプションがあると思います。

  • 受け取った XMLを変更して、文字エンコーディングを含めます。返される XML は Latin-1 でエンコードされていますが、XML タグには<?xml version="1.0"?>. 次のように変更できます<?xml version="1.0" encoding="ISO-8859-1"?>。それが NSXMLParser の問題を解決するかどうかはわかりませんが、そうかもしれません。

  • 上記のように、必要な文字セットをGoogleにリクエストします。リクエストにヘッダーを追加するAccept-Charsetとうまくいきますが、データの取得が少し複雑になります。

于 2012-08-06T17:11:58.933 に答える
-2

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;
}
于 2012-08-06T16:52:49.953 に答える