Web Url contains Spanish Characters which my NSXMLParser is not parsing - iphone

I am Parsing Web urls from server and storing them in Strings and then displaying it on Webview. But now when i am parsing Spanish words like
http://litofinter.es.milfoil.arvixe.com/litofinter/PDF/Presentación_LITOFINTER_(ES).pdf
it is accepting it
PDF File Name ++++++ http://litofinter.es.milfoil.arvixe.com/litofinter/PDF/Presentaci
PDF File Name ++++++ ón_LITOFINTER_(ES).pdf
i.e two different strings... i know i have to make small change that is append the string but i am not able to do it now, can anyone help me out. Here is my code :-
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
currentElement = elementName;
if([currentElement isEqualToString:#"category"]) {
NSLog(#"Current element in Category:- %#",currentElement);
obj = [[Litofinter alloc]init];
obj.productsArray = [[NSMutableArray alloc]init];
}
if([currentElement isEqualToString:#"Product"]) {
obj.oneObj = [[Products alloc]init];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if([currentElement isEqualToString:#"Logo"]) {
obj.cLogo=[NSString stringWithFormat:#"%#",string];
NSLog(#"Logo to be saved in Array :- %#",obj.cLogo);
}
if([currentElement isEqualToString:#"Name"]) {
obj.cName=[NSString stringWithFormat:#"%#",string];
NSLog(#"Name to be saved in Array :- %#",string);
}
if([currentElement isEqualToString:#"cid"]) {
obj.cId=(int)[NSString stringWithFormat:#"%#",string];
NSLog(#"CID to be saved in Array :- %#",string);
}
if([currentElement isEqualToString:#"pid"]) {
//obj.oneObj.id = (int)[NSString stringWithFormat:#"%#",oneBook.id];
obj.oneObj.id = (int)[oneBook.id intValue];
}
if([currentElement isEqualToString:#"Title"]) {
obj.oneObj.title = [NSString stringWithFormat:#"%#",string];
}
if([currentElement isEqualToString:#"Thumbnail"]) {
obj.oneObj.thumbnail= [NSString stringWithFormat:#"%#",string];
}
// problem occuriing while parsing Spanish characters...
if([currentElement isEqualToString:#"pdf"]) {
obj.oneObj.pdf = [NSString stringWithFormat:#"%#",string];
NSLog(#"PDF File Name ++++++ %#",string);
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([elementName isEqualToString:#"category"]) {
NSLog(#"Current element in End Element Category:- %#",currentElement);
[TableMutableArray addObject:obj];
}
if([elementName isEqualToString:#"Product"]) {
[obj.productsArray addObject:obj.oneObj];
}
currentElement = #"";
}
I will be thankful to you.

I found the answer :
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
currentElement = elementName;
// MOdified
else if([currentElement isEqualToString:#"pdf"]) {
// obj.oneObj.pdf = [NSString stringWithFormat:#"%#",string];
// NSLog(#"PDF File Name ++++++ %#",string);
NSMutableString *outputBuilder = [[NSMutableString alloc]init] ;
[outputBuilder appendString:[NSString stringWithFormat:#"%#", self.pdfString]];
[outputBuilder appendString:[NSString stringWithFormat:#"%#", string]];
self.pdfString = outputBuilder;
[outputBuilder release];
}
else
{
self.pdfString = string;
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([currentElement isEqualToString:#"pdf"])
{
obj.oneObj.pdf = self.pdfString;
NSLog(#"PDF File Name ++++++ %#",obj.oneObj.pdf);
}
currentElement = #"";
}
and a small change also that is where i am passing this use this:-
NSString *urlString = [appDelegate.currentBookPressed stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

declare NSString in .h file;
in Did Start parse
str=#"";
if([currentElement isEqualToString:#"pdf"]) {
str=[str stringByAppendingString:string];
obj.oneObj.pdf = [NSString stringWithFormat:#"%#",str];
NSLog(#"PDF File Name ++++++ %#",str);
}

Related

XML response to NSArray

I parse a xml file to get the content of two nodes "tagid" and "mac".
How can I store this content in two arrays, one for "tagid" and one for "mac"?
The "parser" works. Thank you in advance
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
self.currentElement = elementName;
self.currentElement2 = elementName;
if ([self.currentElement isEqualToString:#"mac"]) {
self.currentTitle = [NSMutableString string];
}
if ([self.currentElement2 isEqualToString:#"tagid"]) {
self.currentTitle2 = [NSMutableString string];
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([self.currentElement isEqualToString:#"mac"]) {
NSLog(#"%#", self.currentTitle);
}
if ([self.currentElement2 isEqualToString:#"tagid"]) {
NSLog(#"%#", self.currentTitle2);
}
self.currentTitle = nil;
self.currentElement = nil;
self.currentTitle2 = nil;
self.currentElement2 = nil;
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if (!self.currentElement) return;
if ([self.currentElement isEqualToString:#"mac"]) {
self.currentTitle = string;
}
if (!self.currentElement2) return;
if ([self.currentElement2 isEqualToString:#"tagid"]) {
self.currentTitle2 = string;
}
}
- (IBAction)aktualisieren:(id)sender {
NSURL *xmlURL = [[NSURL alloc] initWithString:#"http://mysite/mycontent"];
parser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
[parser setDelegate:self];
[parser parse];
}
Thank you for your responses :)
create two arrays in parseStartDocument. one for mac-MacArray , one for tagid-tagArray.
in didEndElement method,check for element & add your self.currentTitle to that perticular your Array.
In .h declare two arrays tagArray and macArray.
In viewDidLoad alloc init both arrays.
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([self.currentElement isEqualToString:#"mac"]) {
[macArray addObject:self.currentTitle];
NSLog(#"%#", self.currentTitle);
}
if ([self.currentElement2 isEqualToString:#"tagid"]) {
[macArray addObject:self.currentTitle2];
NSLog(#"%#", self.currentTitle2);
}
self.currentTitle = nil;
self.currentElement = nil;
self.currentTitle2 = nil;
self.currentElement2 = nil;
}
You need two different arrays
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
self.currentElement = elementName;
self.currentElement2 = elementName;
if ([self.currentElement isEqualToString:#"mac"]) {
self.currentTitle = [NSMutableString string];
NSMutableArray *macArray = [NSMutableArray alloc] init];
}
if ([self.currentElement2 isEqualToString:#"tagid"]) {
self.currentTitle2 = [NSMutableString string];
NSMutableArray *tagIdArray = [NSMutableArray alloc] init];
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([self.currentElement isEqualToString:#"mac"]) {
NSLog(#"%#", self.currentTitle);
[macArray addObject:self.currentTitle];
}
if ([self.currentElement2 isEqualToString:#"tagid"]) {
NSLog(#"%#", self.currentTitle2);
[tagIdArray addObject:self.currentTitle2];
}
self.currentTitle = nil;
self.currentElement = nil;
self.currentTitle2 = nil;
self.currentElement2 = nil;
}
Declare two mutable arrays:
NSMutableArray *macArray , *tagidArray;
macArray = [[NSMutableArray alloc]init];
tagidArray = [[NSMutableArray alloc]init];
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([self.currentElement isEqualToString:#"mac"]) {
[macArray addObject:self.currentTitle];
NSLog(#"%#", self.currentTitle);
}
if ([self.currentElement2 isEqualToString:#"tagid"]) {
[tagidArray addObject:self.currentTitle2];
NSLog(#"%#", self.currentTitle2);
}
}
-(void)parserDidEndDocument{
//Do something as parsing has been completed here and your values are in two arrays
}
Find detailed parsing example here
By the way, if either of these was a long string, might get separated into multiple calls to foundCharacters. Thus, foundCharacters should always append strings, not setting strings:
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if (!self.currentElement) return;
if ([self.currentElement isEqualToString:#"mac"]) {
[self.currentTitle appendString:string];
}
if (!self.currentElement2) return;
if ([self.currentElement2 isEqualToString:#"tagid"]) {
[self.currentTitle2 appendString:string];
}
}

How to retrieve country name from xmlParser

I am trying to retrieve countries name from a xml. Here is the xml result.
<Table diffgr:id="Table1" msdata:rowOrder="0"><id>1</id><country>Afghanistan</country><isd_code>93</isd_code><timezone>+04:30</timezone><visible>false</visible></Table><Table diffgr:id="Table2" msdata:rowOrder="1"><id>2</id><country>Albania</country><isd_code>355</isd_code><timezone>+01:00</timezone><visible>false</visible></Table>
In parser did end element method
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ( [elementName isEqualToString:#"Table"] ) {
NSLog(#"attribute is %#",attributeDict);
}
}
OutPut is
attribute is {
"diffgr:id" = Table1;
"msdata:rowOrder" = 0;
}
How can i retrieve country name.
Thanks in advance.
Try this,
in viewDidLoad:-
countryarr=[[NSMutableArray alloc]init];
nodeContent=[[NSMutableString alloc]init];
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
[nodeContent appendString:[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"country"])
{
[countryarr addObject:nodeContent];
}
nodeContent=[[NSMutableString alloc]init];
}
Give this a try
NSString *elementname;
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
elementname = elementName;
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if([elementname isEqualToString:#"country"])
{
NSLog(#"country name is : %#",string);
}
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
elementname = elementName;
}
Try this directly in -(void)connectionDidFinishLoading:(NSURLConnection *)connection Method
Code ::
NSString *theXML = [[[NSString alloc] initWithBytes: [responseData mutableBytes] length:[responseData length] encoding:NSUTF8StringEncoding] autorelease];
theXML = [theXML stringByReplacingOccurrencesOfString:#"<" withString:#"<"];
theXML = [theXML stringByReplacingOccurrencesOfString:#">" withString:#">"];
theXML = [theXML stringByReplacingOccurrencesOfString:#"&" withString:#"&"];
NSLog(#" String :: %#", theXML);
[arrCountry removeAllObjects];
NSArray *arr = [theXML componentsSeparatedByString:#"<Your Main Parent>"];
NSLog(#"Count :: %d", [arr count]);
for(int i = 1; i < [arr count]; i++)
{
NSString *str = [arr objectAtIndex:i];
NSArray *arr1 = [str componentsSeparatedByString:#"<Table>"];
NSString *data = [arr1 objectAtIndex:1];
NSRange ranfrom = [data rangeOfString:#"</Table>"];
for(int i = 1; i < [arr1 count]; i++)
{
NSString *str1 = [arr1 objectAtIndex:i];
NSArray *arr12 = [str1 componentsSeparatedByString:#"<country>"];
NSString *data1 = [arr12 objectAtIndex:1];
NSRange ranfrom1 = [data1 rangeOfString:#"</country>"];
[arrCountry addObject:[data1 substringToIndex:ranfrom1.location]];
}
}
[connection release];
It'll help you.
Thanks.

XML Parse not showing elements with & symbol inside

Im trying to parse a xml feed in my app... The xml file is in this url
feeds.feedburner.com/blogspot/TUvAW?format=xml
The problem is that when I access the description segment it diplays different special symbols such as quotation marks. This is one of the descripton segments im trying to parse from my xml:
<description>Este es mi blog 3<img src="http://feeds.feedburner.com/~r/blogspot/TUvAW/~4/URCV9ModTR0" height="1" width="1"/></description>
Im parsing it with the NSXMLParser, these are the method I'm using in my:
XMLParser.m
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
currentNodeContent = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementname isEqualToString:#"item"])
{
currentFeed = [Feed alloc];
isStatus = YES;
}
if ([elementname isEqualToString:#"author"])
{
isStatus = NO;
}
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if (isStatus)
{
if ([elementname isEqualToString:#"description"])
{
currentFeed.description = currentNodeContent;
NSLog(#"%#",currentNodeContent);
}
if ([elementname isEqualToString:#"title"])
{
currentFeed.content = currentNodeContent;
NSLog(#"%#",currentNodeContent);
}
if ([elementname isEqualToString:#"link"])
{
currentFeed.WVUrl = currentNodeContent;
NSLog(#"%#",currentNodeContent);
}
}
if ([elementname isEqualToString:#"item"])
{
[self.feeds addObject:currentFeed];
currentFeed = nil;
currentNodeContent = nil;
}
}
Im using those NSLogs to track the strings that Im getting from the parse but my description node content is always showing just this : >
The title and link nodes are displaying perfectly.
I want to get all that string from the description node to use it later but simply I can't, I dont know whats going wrong with this.
The problems have been outlined by Abhishek, Rob and me. But I think it's worth to summarize it and show the correct solution.
The main problem is that parser:foundCharacters: is called several times for the <description> tag, each call providing a piece of the description.
The solution is to concatenate the pieces:
XMLParser.h:
NSMutableString* currentNodeContent;
XMLParser.m:
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (currentNodeContent == nil)
currentNodeContent = [[NSMutableString alloc] initWithCapacity: 20];
[currentNodeContent appendString: [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
}
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementname isEqualToString:#"item"])
{
currentFeed = [Feed alloc];
isStatus = YES;
}
if ([elementname isEqualToString:#"author"])
{
isStatus = NO;
}
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if (isStatus)
{
if ([elementname isEqualToString:#"description"])
{
currentTweet.description = currentNodeContent;
NSLog(#"%#",currentNodeContent);
}
if ([elementname isEqualToString:#"title"])
{
currentTweet.content = currentNodeContent;
NSLog(#"%#",currentNodeContent);
}
if ([elementname isEqualToString:#"link"])
{
currentFeed.WVUrl = currentNodeContent;
NSLog(#"%#",currentNodeContent);
}
}
if ([elementname isEqualToString:#"item"])
{
[self.feeds addObject:currentFeed];
currentFeed = nil;
[currentNodeContent release];
currentNodeContent = nil;
}
}
The problem in the Xml file is use of "&" Character.
Do one this just get the xml data in one string and then replace "&" with any unique string and then parse your xml.
While showing or use of xml data just check if the string you are getting contains the same unique string in it then replace that string with the "&".

Parsing with NSXMLParser

I have a xml file with this:
<name>Alberto</name>
<subname>Martín</subname>
<age>24</age>
I want parser it with NSXMLParser and save data it in:
NSString *name;
NSString *subname;
NSString *age;
To do it im using:
-(void) parser:(NSXMLParser *) parser didStartElement:(NSString *)
elementName namespaceURI (NSString *) namespaceURI
qualifiedName:(NSString *) qName
attributes:(NSDictionary *) attributeDict {
if( [elementName isEqualToString:#"name"])
{
if (!soapResults)
{
soapResults = [[NSMutableString alloc] init];
}
elementoEncontrado = YES;
}}
-(void)parser:(NSXMLParser *) parser foundCharacters:(NSString *)string{
if (elementoEncontrado)
{
[soapResults appendString: string];
}
}
-(void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"name"])
{
name=soapResults;
}
if ([elementName isEqualToString:#"subname"])
{
subname=soapResults;
}
if ([elementName isEqualToString:#"age"])
{
age=soapResults;
}
NSLog(#"%#", name, subname, age);
The problem is that subname and age never appears...
You should check for all elements here, since you're only creating the NSMutableString for name elements.
-(void) parser:(NSXMLParser *) parser didStartElement:(NSString *)
elementName namespaceURI (NSString *) namespaceURI
qualifiedName:(NSString *) qName
attributes:(NSDictionary *) attributeDict {
if( [elementName isEqualToString:#"name"])
{
if (!soapResults)
{
soapResults = [[NSMutableString alloc] init];
}
elementoEncontrado = YES;
}
}
and release / nil your soapResults here, as well as set your elementoEncontrado to NO here
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"name"])
{
// copy or retain this, unless ARC.
name=soapResults;
}
if ([elementName isEqualToString:#"subname"])
{
subname=soapResults;
}
if ([elementName isEqualToString:#"age"])
{
age=soapResults;
}
NSLog(#"%#", name, subname, age);
[soapResults release];
soapResults = nil;
elementoEncontrado = NO;
}

Issues with leaking XMLParser

I've been trying for some time now to get xml parser working leak free and efficient but so far unsuccessful. I've removed additional fields as they are all the same.
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
currentElement = [[elementName copy] autorelease];
if ([elementName isEqualToString:#"source"]) {
if (!currentID) {
overlays = [[NSMutableArray alloc] init];
currentID = [[NSMutableString alloc] init];
} else {
[currentID release];
currentID = nil;
currentID = [[NSMutableString alloc] init];
}
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"source"]) {
overlay = [[NSMutableDictionary alloc] init];
[overlay setObject:currentID forKey:#"id"];
[overlays insertObject:overlay atIndex:[overlays count]];
[overlay release];
overlay = nil;
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
string = [string stringByReplacingOccurrencesOfString:#"\n" withString:#""];
string = [string stringByReplacingOccurrencesOfString:#"\t" withString:#""];
if ([currentElement isEqualToString:#"id"]) {
[self.currentID appendString:string];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
[currentID release];
currentID = nil;
//[self addResources];
}
Any help would be appreciated.
If you have declared properties for your ivars I would recommend to use them. This makes memory management easier. This is how I would write your code:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
self.currentElement = elementName;
if ([elementName isEqualToString:#"source"]) {
if (!self.currentID) {
self.overlays = [NSMutableArray array];
self.currentID = [NSMutableString string];
} else {
self.currentID = [NSMutableString string];
}
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"source"]) {
[self.overlays addObject:
[NSDictionary dictionaryWithObjectsAndKeys:self.currentID,#"id",nil]];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
string = [string stringByReplacingOccurrencesOfString:#"\n" withString:#""];
string = [string stringByReplacingOccurrencesOfString:#"\t" withString:#""];
if ([self.currentElement isEqualToString:#"id"]) {
[self.currentID appendString:string];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
self.currentID = nil;
}
You might also want to try Build&Analyse for your code. this may point out where you are leaking.