XML parsing text encoding problem - iphone

I need to parse a XML feed with french accent like 'é' .
When I parse the XML I lost the accents...
What's wrong in my code...
NSString *url = [NSString stringWithFormat:#"%#",#"my_xml_url"];
NSURL *myURL = [NSURL URLWithString:url];
NSString *myData = [[NSString alloc] initWithContentsOfURL:myURL];
XMLParser *parser = [[XMLParser alloc] init];
[parser parseXMLFile:myData];
And when I start parsing.....
- (void)parseXMLFile:(NSString *)data {
BOOL success;
//array for the ranking
rows = [[NSMutableArray alloc] init];
index = 0;
self.currentString = [NSMutableString string];
storingCharacters = NO;
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:[data data UsingEncoding:NSUTF8StringEncoding]];
[parser setDelegate:self];
[parser setShouldResolveExternalEntities:YES];
success = [parser parse];
self.currentString = nil;
//release memory
[parser release];
}
I can't see where is the problem...
Thanks

It appears to be an encoding issue with stringWithContentsOfURL
Try:
NSError *lookupError = nil;
NSString *myData = [NSString stringWithContentsOfURL:myUrl
encoding:NSUTF8StringEncoding error:&lookupError];

You're first reading the XML data and converting it to an NSString, then later converting that string back into data. As krtrego said, the to-string conversion is probably picking the wrong encoding. Instead, you should feed the raw data from the URL directly into NSXMLParser, which is smarter about being able to interpret the correct encoding (i.e. using the metadata at the top of the XML file.)
So instead use
NSData* myData = [[NSData dataWithContentsOfURL: url options: 0 error: &error];
then pass that data when initializing the NSXMLParser.

Related

NSXMLParser parsing xml file encoded using Windows-1256

i want to parse rss file in Windows-1256" encoding but it is not being read by parser
i done alot of parsing in UTF8 encoding but only this don't work why?
rss file with Windows-1256
Solved
solution is
NSString *myStr = [[NSString alloc] initWithData:myData encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingWindowsArabic) ];
myStr = [myStr stringByReplacingOccurrencesOfString:#"encoding=\"windows-1251\"" withString:#""];
NSData* aData = [myStr dataUsingEncoding:NSUTF8StringEncoding];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:aData];
Thank you Mohamed for the answer I kept working on it for 10 days and we found no answers at all. This is my code:
-(void)parseXMLFileAtURL:(NSString *)URL {
NSURL *xmlURL = [NSURL URLWithString:URL];
NSData * dataXml = [[NSData alloc] initWithContentsOfURL:xmlURL];
NSString *myStr = [[NSString alloc] initWithData:dataXml encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingWindowsArabic)];
myStr = [myStr stringByReplacingOccurrencesOfString:#"encoding=\"windows-1256\"" withString:#""];
NSData *aData = [myStr dataUsingEncoding:NSUTF8StringEncoding];
NSXMLParser *rssParser = [[NSXMLParser alloc] initWithData:aData];
[dataXml release];
[rssParser setDelegate:self];
[rssParser setShouldProcessNamespaces:NO];
[rssParser setShouldReportNamespacePrefixes:NO];
[rssParser setShouldResolveExternalEntities:NO];
[rssParser parse];
[rssParser setDelegate:nil];
[rssParser release];
}
Also you can try this:
int length = str.length >100 ? 100:str.length;
NSString*mystr= [str stringByReplacingOccurrencesOfString:#"encoding=\".*?\""
withString:#""
options:NSRegularExpressionSearch
range:NSMakeRange(0, length)];
If you implement the parseErrorOccurred: method in your NSXMLParser delegate, it will give you the exact reason for the errors.
Something like:
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
    NSLog(#"NSXMLParser ERROR: %# - %#", , [parseError localizedDescription], [parseError localizedFailureReason]);
}

xml parsering from webserver in iphone

To all
I am trying to parser the xml in my project But I have the code for xml parsing for locally I want the server base xml parsing how can i pass that
This is my xml parsing link i want to use:
http://www.google.com/ig/api?weather=,,,50500000,30500000
This my xml parsing for calling local file how can I call my webserver xml link for parsing.I need different-differnet type of calling xml link for parsing:
- (void)viewDidLoad
{
[super viewDidLoad];
_forecastInfo=nil;
currentcond=nil;
forecastcond=nil;
// Pass the NSData to the parser whether its from local file or its coming from web.... NSString *fileName=[[NSBundle mainBundle] pathForResource:#"weather" ofType:#"xml"];
NSData *data=[NSData dataWithContentsOfFile:fileName];
ForecastInfoParser *parser=[[ForecastInfoParser alloc]init];
parser.delegate=self;
[parser parseData:data];
}
NSURL *url = [[NSURL alloc] initWithString:#"hhttp://www.google.com/ig/api?weather=,,,50500000,30500000"];
NSData *data = [NSData dataWithContentsOfURL:url];
// 2 -- parsing
parser = [[MyParser alloc] init];
[parser parseXML:data];
NSString *URL=#"http://www.google.com";
NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:URL]];
NSURLResponse *resp = nil;
NSError *err = nil;
NSData *response = [NSURLConnection sendSynchronousRequest: theRequest returningResponse: &resp error: &err];
NSString * theString = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
[resp release];
[err release];
NSLog(#"response: %#", theString);

Load XML from documents directory - iPhone

Instead of loading a XML from the URL, I would like to load it from the documents directory(which i saved when there is Internet connection)
NSString* filename=#"magzine.xml";
NSData *data=[NSData dataWithContentsOfURL:[[NSURL alloc] initWithString:[URLlink stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
NSString *applicationDocumentsDir =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *storePath = [applicationDocumentsDir stringByAppendingPathComponent:filename];
[data writeToFile:storePath atomically:YES];
NSLog(#"URL: %#",url);
xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
//xmlParser = [[NSXMLParser alloc] initWithContentsOfFile:filename];
[xmlParser setDelegate:self];
[xmlParser parse];
Now i am getting the xml from url ,that is from initwithcontentsofurl,Now i want to get the saved file from documents directory when there is no internet connection.Please help me in this ,how to load the xml??
THANKS IN ADVANCE
Here is an example on how to load and parse local XML files on the iPhone.

How to use stringWithContentsOfURL:encoding:error:?

I am trying to use initWithContentsOfURL:encoding:error: like this :
NSURL *url = [[NSURL alloc] initWithString:#"http://my_url.com/my_file.xml"];
NSError *error = nil;
NSString *my_string = [[NSString alloc] initWithContentsOfURL:url
encoding:NSUTF8StringEncoding
error:&error];
I get a empty my_string variable.
I tried the initWithContentsOfURL: method (which is deprecated in iOS 2.0) and I get the content of my page. But I still need to specify a encoding language.
What's wrong ?
Thanks :)
the encoding of your file is probably not UTF8.
If you don't know the encoding of your file, you could try this method:
- (id)initWithContentsOfURL:(NSURL *)url usedEncoding:(NSStringEncoding *)enc error:(NSError **)error
you have to pass a pointer to a NSStringEncoding, like you did with error.:
NSURL *url = [[NSURL alloc] initWithString:#"http://my_url.com/my_file.xml"];
NSError *error = nil;
NSStringEncoding encoding;
//NSString *my_string = [[NSString alloc] initWithContentsOfURL:url
// encoding:NSUTF8StringEncoding
// error:&error];
NSString *my_string = [[NSString alloc] initWithContentsOfURL:url
usedEncoding:&encoding
error:&error];
after this your encoding is present in the encoding variable. If you are not interested in the used encoding, I guess you could pass NULL as pointer as well.
Why not use a request and connection to get the info back in an NSData object? Something like this:
NSURL *url = [[NSURL alloc] initWithString:#"http://my_url.com/my_file.xml"];
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:url];
[request setHTTPMethod:#"GET"];
NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:request delegate:self];
[conn start];
if(conn){
// Data Received
responseData = [[NSMutableData alloc] init];
}
and then in your connection:didRecieveData delegate method, put something like this
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[self.responseData appendData:data];
}
and then once the connection is finished loading convert the data to a string:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSString *string = [[NSString alloc] initWithData:responseData encoding:NSASCIIStringEncoding];
}
Not the most straightforward method, but that should get you your XML string. Also if you need to parse the XML once you get it back, you can directly pass the responseData to an NSXMLParser without any conversion. :)
You can modify your webpage by adding header('Content-Type: text/html; charset=UTF-8'); to the top of the code and saving the document as a UTF-8 formated file. It helped me as I had the same problem.

Continuous conversion of text to speech from json data

I am designing an app that needs text to speech. I am using the library that is posted here to convert text to speech. I have to retrieve text from Json url, and pass the values to text to speech. I am able to retrieve Json data and convert it to text to speech for the ObjectatIndex 0 using the following code...
SBJSON *json = [[SBJSON alloc]init];
fliteEngine = [[FliteTTS alloc] init];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.sampleurl.txt"]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *jsonstring = [[NSString alloc]initWithData:response encoding:NSUTF8StringEncoding];
NSArray *asanasList = [json objectWithString:jsonstring error:nil];
NSArray *asanas =[asanasList objectForKey:#"yogagurubackpain"];
for(NSDictionary *test in asanas)
{
UrlValues *myasanas = [[UrlValues alloc]init];
myasanas.asanatitle = [test objectForKey:#"asanatitle"];
myasanas.asanatranscript = [test objectForKey:#"asanatranscript"];
myasanas.asanapicture = [test objectForKey:#"asanapicture"];
[data.yoga addObject:myasanas];
[myasanas release];
}
UrlValues *asana=[[data yoga]objectAtIndex:0];
self.AsanaName.text = [asana asanatitle];
self.AsanaTranscript.text = [asana asanatranscript];
NSString *imageUrl = [asana asanapicture];
NSString* mapUrl = [imageUrl stringByReplacingPercentEscapesUsingEncoding:NSASCIIStringEncoding];
NSData* imageData = [[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:mapUrl]];
UIImage* image = [[UIImage alloc] initWithData:imageData];
self.AsanaImage.image = image;
NSString *speak = self.AsanaTranscript.text;
[fliteEngine setVoice:#"cmu_us_rms"];
[fliteEngine speakText:speak];
[fliteEngine setPitch:100.0 variance:11.0 speed:0.4];
[imageData release];
[image release];
[jsonstring release];
[json release];
Now my problem is how can i go to the next object automatically after completion of the playing of first one. The process must continue for all the objects. The corresponding images etc must load on the page after the text to speech is done for the first one... Plz help me...
Looking at the source of the linked library, it looks like you'll have to hack a method into FliteTTS.m. If you look at the source, it's using an AVAudioPlayer to play back a generated WAV file. It's also setting itself as the audio player's delegate. If you implement the audioPlayerDidFinishPlaying:successfully: delegate method and play the next chunk when it's called, you should be able to have a semi-continuous text-to-speech stream.