I am able to parse the xml data and able to display it in the console, but not able to display that data in the UITextField or in UILabel.
I tried to assign to textfield in the viewDidLoad method also.
The following is my code,
NSMutableString *currentNodeContent;
NSXMLParser *parser;
ViewController *currentProfile;
bool isStatus;
ViewController *xmlParser;
-(id)loadXMLByURL:(NSString *)urlString
{
_profile = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
parser = [[NSXMLParser alloc] initWithData:data];
parser.delegate = self;
[parser parse];
return self;
}
-(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:#"profileinfo"])
{
currentProfile = [ViewController alloc];
isStatus = YES;
}
if([elementName isEqualToString:#"first_name"])
{
currentProfile = [ViewController alloc];
isStatus = YES;
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([elementName isEqualToString:#"first_name"])
{
currentProfile.firstName = currentNodeContent;
NSLog(#"%#",currentProfile.firstName);
first_Name.text = currentNodeContent;//UITextField
first_name.text = currentNodeContent;//Label
}
if([elementName isEqualToString:#"last_name"])
{
currentProfile.lastName = currentNodeContent;
NSLog(#"%#",currentProfile.lastName);
last_Name.text = currentProfile.lastName;
}
if([elementName isEqualToString:#"profileinfo"])
{
[self.profile addObject:currentProfile];
currentProfile = nil;
currentNodeContent = nil;
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
xmlParser = [[ViewController alloc] loadXMLByURL:#"http://www.mxxxxx.net/xxx/xxxxx.aspx?type=proifileinfo&loginid=xxx#gmail.com"];
}
Instead of assigning the values directly to the 'UITextField' or 'UILabel', have the values stored in a string. And when the parsing action completed, assign the string value to the 'UITextField' or 'UILabel'; Probably you should do that in '-viewWillAppear' method :-)
Create a IBOutlet UILabel *label; in the interface, connect it in Interface Builder, and then you can set the text of it by label.text = #"Anything";
I have also the same problem while parsing XML parser.
currentNodeContent = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
You are using the above line to trim spaces and tabs. But sometimes It does not work.
So, I implement the following code. The code may be useful to you.
NSString *sname = [currentNodeContent stringByReplacingOccurrencesOfString:#"\n" withString:#""];
NSString *actualString = [sname stringByReplacingOccurrencesOfString:#"\t" withString:#""];
Then pass the actualString to whatever you required.
Related
I'm actually doing parsing at the start of my program and this is my parser.m class i found
"leak" in this class in method "foundCharacters" in line
currentElementValue = [[NSMutableString alloc] initWithString:string];
currentElementValue is NSMutableString which is declare in parser.h file
NSMutableString *currentElementValue;
Can any one suggest me the way to solve this leak which some times crash my app in the starting...
Thanks In Advance...
didStartElement Method:-
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {
if([elementName isEqualToString:#"posts"]) {
appDelegate.newsArray = [[NSMutableArray alloc] init];
}
else
{
if([elementName isEqualToString:#"page"])
{
aNewsInfo = [[NewsInfo alloc] init];
aNewsInfo.page = [[attributeDict objectForKey:#"id"] integerValue];
}
if(![elementName compare:#"smallimage"])
{
currentElementValue = [NSMutableString string];
}
if(![elementName compare:#"largeimage"])
{
currentElementValue = [NSMutableString string];
}
}
NSLog(#"Processing Element :%#",elementName);
}
Leak found in this foundCharacter method:- in line....
currentElementValue = [[NSMutableString alloc] initWithString:string];
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if(!currentElementValue)
currentElementValue = [[NSMutableString alloc] initWithString:string];
else
[currentElementValue appendString:string];
NSLog(#"Processing Value: %#", currentElementValue);
}
didEndElement method:-
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if([elementName isEqualToString:#"posts"])
return;
if([elementName isEqualToString:#"page"]) {
[appDelegate.newsArray addObject:aNewsInfo];
NSLog(#"%d",[appDelegate.newsArray count]);
NSLog(#"%#",aNewsInfo.title);
NSLog(#"%#",aNewsInfo.fulltext);
[aNewsInfo release];
aNewsInfo = nil;
}
else {
if ([elementName isEqualToString:#"smallimage"])
{
NSURL *url = [NSURL URLWithString:currentElementValue];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [[UIImage alloc] initWithData:data];
[aNewsInfo setSmallImageData:image];
}
if(![elementName compare:#"largeimage"])
{
NSURL *imageURL = [NSURL URLWithString:currentElementValue];
NSData *data = [NSData dataWithContentsOfURL:imageURL];
UIImage *image = [[UIImage alloc] initWithData:data];
[aNewsInfo setLargeImageData:image];
[image release];
}
[aNewsInfo setValue:currentElementValue forKey:elementName];
[currentElementValue release];
currentElementValue = nil;
}
}
First of all you need to do some study:
Go to following links:
http://www.cocoadev.com/index.pl?MemoryManagement
http://mattpatenaude.com/ch3-memory-management.html
http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/memorymgmt/Articles/MemoryMgmt.html
then do this,
currentElementValue = [[[NSMutableString alloc] initWithString:string] autorelease]
and remove [currentElementValue release], from
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
(otherwise it will leads to crash due to over releasing)
I'm following a tutorial and it's working fine but if I wanted to parse 2 RSS feeds it seems to overwrite one array instead of saving them in the respective arrays.
This is in my delegate:
NSURL *url2 = [[NSURL alloc] initWithString:#"myRSSFEED1"];
NSXMLParser *xmlParser1 = [[NSXMLParser alloc] initWithContentsOfURL:url2];
//Initialize the delegate.
XMLParser1 *parser1 = [[XMLParser1 alloc] initXMLParser];
//Set delegate
[xmlParser1 setDelegate:parser1];
//Start parsing the XML file.
BOOL successs = [xmlParser1 parse];
if(successs)
NSLog(#"No Errors");
else
NSLog(#"Error Error Error!!!");
//VIDS
NSURL *url = [[NSURL alloc] initWithString:#"MYRSSFEED2"];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
//Initialize the delegate.
XMLParser *parser = [[XMLParser alloc] initXMLParser];
//Set delegate
[xmlParser setDelegate:parser];
//Start parsing the XML file.
BOOL success = [xmlParser parse];
if(success)
NSLog(#"No Errors");
else
NSLog(#"Error Error Error!!!");
that parses feed 1, allocates it to the array then parses 2 and seems to overwrite the first insteaf of using the second array that are defined as
#synthesize pics;
#synthesize books;
And saved in my XMLParser & XMLParser1
I can't figure out how to stop it from overwriting.
Here is my XMLParsers too:
- (void)parsers:(NSXMLParser *)parsers didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {
if([elementName isEqualToString:#"Books"]) {
//Initialize the array.
appDelegate2.pics = [[NSMutableArray alloc] init];
}
else if([elementName isEqualToString:#"Book"]) {
//Initialize the book.
apics = [[BookPhoto alloc] init];
//Extract the attribute here.
apics.bookID = [[attributeDict objectForKey:#"id"] integerValue];
NSLog(#"Reading HAVid value :%i", apics.bookID);
}
NSLog(#"Processing Element: %#", elementName);
}
- (void)parsers:(NSXMLParser *)parsers foundCharacters:(NSString *)string {
if(!currentElementValue)
currentElementValue = [[NSMutableString alloc] initWithString:string];
else
[currentElementValue appendString:string];
NSLog(#"Processing Value: %#", currentElementValue);
}
- (void)parsers:(NSXMLParser *)parsers didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if([elementName isEqualToString:#"Books"])
return;
//There is nothing to do if we encounter the Books element here.
//If we encounter the Book element howevere, we want to add the book object to the array
// and release the object.
if([elementName isEqualToString:#"Book"]) {
[appDelegate2.pics addObject:apics];
[apics release];
apics = nil;
}
else
[apics setValue:currentElementValue forKey:elementName];
[currentElementValue release];
currentElementValue = nil;
}
And my XMLParser.m
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {
if([elementName isEqualToString:#"Books"]) {
//Initialize the array.
appDelegate.books = [[NSMutableArray alloc] init];
}
else if([elementName isEqualToString:#"Book"]) {
//Initialize the book.
aBook = [[Book alloc] init];
//Extract the attribute here.
aBook.bookID = [[attributeDict objectForKey:#"id"] integerValue];
NSLog(#"Reading id value :%i", aBook.bookID);
}
NSLog(#"Processing Element: %#", elementName);
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if(!currentElementValue)
currentElementValue = [[NSMutableString alloc] initWithString:string];
else
[currentElementValue appendString:string];
NSLog(#"Processing Value: %#", currentElementValue);
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if([elementName isEqualToString:#"Books"])
return;
//There is nothing to do if we encounter the Books element here.
//If we encounter the Book element howevere, we want to add the book object to the array
// and release the object.
if([elementName isEqualToString:#"Book"]) {
[appDelegate.books addObject:aBook];
[aBook release];
aBook = nil;
}
else
[aBook setValue:currentElementValue forKey:elementName];
[currentElementValue release];
currentElementValue = nil;
}
Any help on this would be brilliant,
I suggest putting a breakpoint at the point where the array is not getting loaded, and seeing if (1) it even gets called, and (2), whether it is saving the data into the array at all.
my bad
seems i had extra s's in parser:
- (void)parsers:(NSXMLParser *)parsers foundCharacters:(NSString *)string {
if(!currentElementValue)
currentElementValue = [[NSMutableString alloc] initWithString:string];
else
[currentElementValue appendString:string];
NSLog(#"Processing Value: %#", currentElementValue);
}
should have been:
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if(!currentElementValue)
currentElementValue = [[NSMutableString alloc] initWithString:string];
else
[currentElementValue appendString:string];
NSLog(#"Processing Value: %#", currentElementValue);
}
cheers for the help tho
This question already has answers here:
NSXMLParser Leaking
(4 answers)
Closed 2 years ago.
My NSXMLParser is leaking and I don't know why! Instrument is saying, in the extended details, that the source is 100% from [Parser parse];
Picture: Instruments leaks
This is my code for allocating and releasing the NSXMLParser:
NSURL *xmlURL = [NSURL URLWithString:#"http://www.website.com/link.xml"];
NSData * dataXml = [[NSData alloc] initWithContentsOfURL:xmlURL];
Parser = [[NSXMLParser alloc] initWithData:dataXml];
[dataXml release];
Parser.delegate = self;
[Parser parse];
[Parser release];
The delegate methods
//Standard function parser: reading open tag
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict{
currentElement = elementName;
if ([elementName isEqualToString:#"item"]) {
xmlArray = [[NSMutableDictionary alloc] init];
}
}
//Standard function parser: reading string
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if ([currentElement isEqualToString:#"created_time"]){
valueKey = [xmlArray valueForKey:currentElement];
if(nil != valueKey)
{
valueKey = [valueKey stringByAppendingString:string];
}else
{
valueKey = string;
}
[xmlArray setObject:valueKey forKey:currentElement];
}
if ([currentElement isEqualToString:#"message"]){
valueKey = [xmlArray valueForKey:currentElement];
if(nil != valueKey)
{
valueKey = [valueKey stringByAppendingString:string];
}else
{
valueKey = string;
}
[xmlArray setObject:valueKey forKey:currentElement];
}
if ([currentElement isEqualToString:#"picture"]){
valueKey = [xmlArray valueForKey:currentElement];
if(nil != valueKey)
{
}else
{
valueKey = string;
}
[xmlArray setObject:valueKey forKey:currentElement];
}
}
//Standard function parser: reading close tag
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"item"]) {
Post *newPost = [[Post alloc] init];
newPost.created_time = [xmlArray objectForKey:#"created_time"];
newPost.message = [xmlArray objectForKey:#"message"];
newPost.picture = [xmlArray objectForKey:#"picture"];
[containerArray addObject:newPost];
[xmlArray release];
[newPost release];
}
}
I suspect that the leak is occurring inside your didStartElement or didEndElement callbacks. Please post these up so that we can check.
I getting this error when retrieve xml request from http://www.cbr.ru/scripts/XML_daily.asp
XML code like this:
<?xml version="1.0" encoding="windows-1251" ?>
<ValCurs Date="01.03.2011" name="Foreign Currency Market">
<Valute ID="R01010">
<NumCode>036</NumCode>
<CharCode>AUD</CharCode>
<Nominal>1</Nominal>
<Name>Австралийский доллар</Name>
<Value>29,3508</Value>
</Valute>
<Valute ID="R01020A">
<NumCode>944</NumCode>
<CharCode>AZN</CharCode>
<Nominal>1</Nominal>
<Name>Азербайджанский манат</Name>
<Value>36,3374</Value>
</Valute>
My code is:
-(void)parserDidStartDocument:(NSXMLParser *)parser
{
[articles removeAllObjects];
}
-(void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict
{
currentElement = elementName;
if ([elementName isEqualToString:#"ValCurs"]) {
itemActive = YES;
currentValute = [[NSMutableString alloc]init];
currentNumCode = [[NSMutableString alloc]init];
currentCharCode = [[NSMutableString alloc]init];
nominal = [[NSMutableString alloc]init];
currentName = [[NSMutableString alloc]init];
currentValue = [[NSMutableString alloc]init];
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (itemActive) {
NSString *fixedString = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([currentElement isEqualToString:#"Valute"])
[currentValute appendString:fixedString];
if ([currentElement isEqualToString:#"NumCode"])
[currentNumCode appendString:fixedString];
if ([currentElement isEqualToString:#"CharCode"])
[currentCharCode appendString:fixedString];
if ([currentElement isEqualToString:#"Nominal"])
[nominal appendString:fixedString];
if ([currentElement isEqualToString:#"Name"])
[currentName appendString:fixedString];
if ([currentElement isEqualToString:#"Value"])
[currentValue appendString:fixedString];
}
}
-(void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"ValCurs"]) {
NSDictionary *record = [NSDictionary dictionaryWithObjectsAndKeys:
currentValute,#"Valute",
currentNumCode,#"NumCode",
currentCharCode,#"CharCode",
nominal,#"nominal",
currentName,#"Name",
currentValue,#"Value",
nil];
[articles addObject:record];
[currentNumCode release];
[currentCharCode release];
[currentValute release];
[nominal release];
[currentName release];
[currentValue release];
itemActive = NO;
}
}
-(void)parserDidEndDocument:(NSXMLParser *)parser
{
NSLog(#"%#",articles);
//text.text = (#"%#",currentCharCode);
}
-(void)retrieveXML:(id)sender
{
[parser parse];
}
........
- (void)viewDidLoad {
[super viewDidLoad];
articles = [[NSMutableArray alloc]init];
NSString *myURL = [NSString stringWithFormat:#"http://www.cbr.ru/scripts/XML_daily.asp"];
NSURL *url = [NSURL URLWithString:myURL];
//NSString *urla = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
parser = [[NSXMLParser alloc]initWithContentsOfURL:url];
parser.delegate = self;
[self createUI];
}
From NSXMLParser reference -NSXMLParserUnknownEncodingError = 31.
May be i need use encoding to NSWindowsCP1251StringEncoding for solve problem ?
NSXMLParserUnknownEncodingError = 31 occurs when document encoding is unknown.
Try this:
NSString *myStr = [[NSString alloc] initWithData:myData encoding:NSWindowsCP1251StringEncoding];
myStr = [myStr stringByReplacingOccurrencesOfString:#"encoding=\"windows-1251\"" withString:#""];
NSData* aData = [myStr dataUsingEncoding:NSUTF8StringEncoding];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:aData];
I have an xml file I am parsing.
NSURL *url = [NSURL URLWithString:#"url.xml"];
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
self.downloadData = [[NSMutableData alloc] initWithLength:0];
self.connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
I have all the connections working and I thought I had the parsing working but I am having issues and do not know what I am doing wrong.
my didStartElement:
-(void) parser:(NSXMLParser *) parser didStartElement:(NSString *) elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *) qName attributes:(NSDictionary *) attributeDict {
if ([elementName isEqualToString:kimgurl])
{
elementFound = YES;
}
}
foundCharacter:
-(void)parser:(NSXMLParser *) parser foundCharacters:(NSString *)string {
if (elementFound == YES) {
if(!currentValue)
{
currentValue = [[NSMutableString alloc] init];
}
[currentValue appendString: string];
}
}
then didEndElement:
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if (elementFound) {
if ([elementName isEqualToString:kimgurl]) {
NSLog(#"imgurl: %#", currentValue);
imageItems.imageURL = currentValue;
NSLog(#"elname: %#", elementName);
NSLog(#"img: %#", kimgurl);
[currentValue setString:#""];
NSLog(#"imageitem: %#", imageItems.imageURL);
}
}
}
I have the NSLogs there because imageItems.imageURL is null. This is a class file that is like this.
ImageItems.h
#interface ImageItems : NSObject {
//parsed data
NSString *imageURL;
}
#property (nonatomic, retain) NSString *imageURL;
#end
ImageItems.m
#import "ImageItems.h"
#implementation ImageItems
#synthesize imageURL;
-(void)dealloc
{
[imageURL release];
[super dealloc];
}
#end
As you can tell by my code I am new to objective-c.
currentValue has the value Im looking for. Why is imageItems null? What am I missing?
I don't see the assignment of "imageItems" anywhere in your code. You probably need to assign it to an instance of ImageItems at some point. Perhaps with self.imageItems = [[[ImageItems alloc] init] autorelease] or imageItems = [[ImageItems alloc] init];?