I have the following method, I have one more method through which I am calling this method, but have no luck yet.
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict{
if ([elementName isEqualToString:#"isphone-config"]) {
Pusername = [attributeDict valueForKey:#"authentication_username"];
Ppassword = [attributeDict valueForKey:#"authentication_password"];
Pidentity = [attributeDict valueForKey:#"sip_identity"];
Pdomain = [attributeDict valueForKey:#"domain"];
Pprotocol = [attributeDict valueForKey:#"protocol"];
Pudpport = [attributeDict valueForKey:#"registrar_port"];
Ptcpport = [attributeDict valueForKey:#"listening_port"];
NSLog(#"Title: %#, ID: %#", Pusername, Ppassword);
}
}
}
And I am calling it from the following method..
NSString* username = [[NSUserDefaults standardUserDefaults] stringForKey:#"username_preference"];
NSString* accountPassword = [[NSUserDefaults standardUserDefaults] stringForKey:#"password_preference"];
NSString* urlString = [NSString stringWithFormat:#"https://%#:%##test.com/test.php",username,accountPassword];
NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
parser = [[NSXMLParser alloc] initWithData: response];
NSLog(#"at parser %#", parser);
[parser setDelegate:self];
I am having issues in the last line of the code from where I am calling parser. I assume that this line will call the method parser, correct me if I am wrong. I don't know which files, interfaces and classes I have to import, include or implement.
XML parsing with NSXMLParser is much more difficult, check Apple's example "earthquakes".
Instead I suggest you to use another XML parser. For example, this one:
Also, good article about how to choose parser.
http://www.raywenderlich.com/725/how-to-read-and-write-xml-documents-with-gdataxml
Related
i have an XML file as url where the file contains like this,
<Products>
<products id="1">
<name>product1</name>
<price>$150</price>
<img>http://www.myimage.com/Main_pic.png</img>
</products>
</Products>
Now using NSXMLParser i can retrieve the data and the image but after i get those data am not understanding how to store in NSMutableArray or NSDictionary. Also i tried to implement lazyloading asynchronous image download from Lazy Loading Table Images Asynchronous Downloading from Apple. But i failed to load the images. Do we have any alternative for aynchronous loading.
Kindly describe me in detail about,
how to store a data retieved from url XML file in aysnchronous downloading.
how to separate data and image.
how to implement those in UIImage and data to view in iPhone.
EDITED
for better understanding i need the data and the image like below picture and not in the table view.
EDITED-2
By using the lazyloading parsing i modified according to my content here the code for your reference,
- (void)main{
self.workingArray = [NSMutableArray array];
self.workingPropertyString = [NSMutableString string];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:dataToParse];
[parser setDelegate:self];
[parser parse];
if (![self isCancelled]){
self.completionHandler(self.workingArray);}
self.workingArray = nil;
self.workingPropertyString = nil;
self.dataToParse = nil;}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
if ([elementName isEqualToString:#"Products"]){
self.workingEntry = [[egsLists alloc] init];}
storingCharacterData = [elementsToParse containsObject:elementName];}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if (self.workingEntry){
if (storingCharacterData){
NSString *trimmedString = [workingPropertyString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[workingPropertyString setString:#""];
if ([elementName isEqualToString:sIDStr]){
self.workingEntry.ProductID = trimmedString;}
else if ([elementName isEqualToString:sImageStr]){
self.workingEntry.img = trimmedString;}}
else if ([elementName isEqualToString:#"Products"]){
[self.workingArray addObject:self.workingEntry];
self.workingEntry = nil;}}}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if (storingCharacterData){
[workingPropertyString appendString:string];}}
take a NSObject Class say DataClass
// create objects for your data in DataClass.h And Synthesize them in DataClass.m
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
DataClass *mydata=[[DataClass alloc]init];
if ([elementName isEqualToString:#"id"])
{
mydata.idvalue=[currentNodeContent stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
if ([elementName isEqualToString:#"name"])
{
mydata.namevalue=[currentNodeContent stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
if ([elementName isEqualToString:#"price"])
{
mydata.pricevalue=[currentNodeContent stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
if ([elementName isEqualToString:#"img"])
{
mydata.imgLink=[currentNodeContent stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
[myArray addObject:mydata];
}
After That When You Need you can Retrive the Data From Array if you are Using TableView
then in your CellForRowAtindexPath method use the following:
DataClass *mydata=[[DataClass alloc]init];
mydata=[myarray objectAtindex:indexPath.row];
cell.textlabel.text=mydata.nameValue;
cell.imageView.image=[UIImage imageWithData: [NSData dataWithContentsOfURL: [NSURL URLWithString:mydata.imglink]]];
You can Use LazyTableImages SampleCode from Apple for Loading Images.
http://developer.apple.com/library/ios/#samplecode/LazyTableImages/Introduction/Intro.html
For Complete XML parsing See the Tutorial or use Below Code:
Source : http://www.theappcodeblog.com/2011/05/09/parsing-xml-in-an-iphone-app-tutorial/
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://opentestdrive.com/Products.xml"]];
// Perform request and get JSON as a NSData object
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *responseString = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding] ;
NSLog(#"responseString=%#", responseString);
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:url]];
[request setHTTPMethod:#"GET"];
NSURLConnection *conn=[[NSURLConnection alloc] initWithRequest:request delegate:self];
if (conn)
{
receivedData = [[NSMutableData data] retain];
}
else
{
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[receivedData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[receivedData appendData:data];
}
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementname isEqualToString:#"imgName"])
{
//if you Taking any NSObject Class then Alloc init here.
}
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementname isEqualToString:#"name"])
{
namelable.text=currentNodeContent;
}
if ([elementname isEqualToString:#"price"])
{
pricelabel.text = currentNodeContent;
}
if ([elementname isEqualToString:#"imgName"])
{
imageView.image=[UIImage imageWithData: [NSData dataWithContentsOfURL: [NSURL URLWithString:currentNodeContent]]];
}
}
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
currentNodeContent = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
Hi iam parsing an xml file and i got the response also which i have stored in a responseString.My problem with the delegate methods which are not being called, here's my parsing code
-(void)getData
{
NSURL *url = [NSURL URLWithString:#"http://quizpro.testshell.net/api/quiz/4"];
NSData *data = [NSData dataWithContentsOfURL:url]; // Load XML data from web
NSString *applicationDocumentsDir =
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *storePath = [applicationDocumentsDir stringByAppendingPathComponent:#"quiz.xml"];
NSLog(#"store path is %#",storePath);
[data writeToFile:storePath atomically:TRUE];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
request.delegate=self;
[request startSynchronous];
NSError *error = [request error];
if (!error)
{
NSData *responseData=[request responseData];
NSString *data =[[[NSString alloc]initWithData:responseData encoding:NSUTF8StringEncoding] autorelease];
NSString *usableXmlString = [data stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSLog(#"usableXmlString is %#",usableXmlString);
NSData *usableData = [usableXmlString dataUsingEncoding:NSUTF8StringEncoding];
NSXMLParser *xmlParser = [[NSXMLParser alloc]initWithData:usableData];
[xmlParser setDelegate:self];
[xmlParser parse];
}
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
NSLog(#"requestFinished method");
// Use when fetching text
NSString *responseString = [request responseString];
** I get the entire data here **
NSLog(#"responseString is %#",responseString);
NSData *xData = [responseString dataUsingEncoding:NSUTF8StringEncoding];
//myCode.text = responseString;
//NSLog(#" response %#", responseString);
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:xData];
[parser setDelegate:self];
[parser parse];
[parser release];
}
And i wrote the NSXMLParser delegate methods like below
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSLog(#"parser/didStartElement");
currentTag = elementName;
if ([currentTag isEqualToString:#"questions"])
{
exams_object=[[ExamsObject alloc]init];
NSLog(#"%#",currentTag);
}
if ([currentTag isEqualToString:#"Question"])
{
exams_object=[[ExamsObject alloc]init];
}
if ([currentTag isEqualToString:#"Response"])
{
exams_object.responseArray=[[NSMutableArray alloc]init];
}
NSLog(#"%#",currentTag);
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
NSLog(#"parser/didEndElement");
if ([currentTag isEqualToString:#"questions"])
{
exams_object=[[ExamsObject alloc]init];
}
if([elementName isEqualToString:#"Question"])
{
[mainArray addObject:exams_object];
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)str
{
NSLog(#"parser/foundCharacters");
if ([currentTag isEqualToString:#"questionText"])
{
[exams_object.questionArray addObject:str];
}
if ([currentTag isEqualToString:#"responseText"])
{
[exams_object.responseArray addObject:str];
}
}
Thanks for help me
Have you included NSXMLParserDelegate and ASIHTTPRequestDelegate in your .h file ?
You are calling the method to parse the XML from delegate of ASIHTTPRequest
Check the flow of execution using breakpoints.
#interface yourClassName: NSObject <NSXMLParserDelegate, ASIHTTPRequestDelegate>
Also check these stackoverflow questions
Question 1
Question 2
Check whether you have added NSXMLParserDelegate in #interface and set parser.delegate=self in the class where you are using.
I need to call an XML file from a WCF Service and parse the content of XML in iPhone. I'm able to call the service URL but when parsing using NSXMLParser, I couldn't get a patricular attribute value in XML. I'm using a ViewController application in XCode.
My XML file is like this:
<GetCompanyResponse xmlns="http://schemas.datacontract.org/2004/07/DomainModel"
xmlns:i="http://www.w3.org/2001/XMLSchema-
<CompanyList>
<Company>
<Id>b9ca2e32-ce88-4d72-99ce-9bc592511e85</Id>
</Company>
</CompanyList>
NSString *urlString = [NSString stringWithFormat:#"http://192.168.0.107:8732/Design_Time_Addresses/IServices/
AppointmentService/json/GetCompany";
NSURL *jsonUrl =[NSURL URLWithString:urlString];
NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:jsonUrl];
[parser setDelegate:self];
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
[parser release];
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:
(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:#"Company"]) {
NSString *name=[attributeDict objectForKey:#"Id"];
}
}
But when I check for the value in 'name' it is returning nil. I don't know what's wrong. What should I change? How can I get the value of the ID attribute?
Any help would be appreciated. Thanks in advance.
id is not attribute of the name. Put code in didEndElement:
define strVal NSString in .h;
Inside found character:
{
strVal=string;
}
Inside parserDidEndElement method:
{
if ([elementName isEqualToString:#"Id"]) {
NSString *name=strVal;
}
}
This will work for you.
Am having a webservice. Need my apple code to connect and pass 3parameters to the web service. Am very new to Objective C. Can anyone provide a sample code or guide me through this? Have searched links in StackOverflow. But not able to understand them.
Thanks In Advance.
NSString *urlString= [NSString stringWithFormat:#"http://demo.xyz.com/proj/webservices/display_records/1/%#%#%#",myid,name,password];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
conn= [[NSURLConnection alloc]initWithRequest:request delegate:self];
if(conn)
{
webdata=[[NSMutableData data]retain];
}
Use defalut connection methods
You using soap message okey then akshar first you create a class of NSObject and then define a method in .h file with 3 parameter as given in below code:-
in .h file
#interface GetPartParser : NSObject <NSXMLParserDelegate>
{
NSXMLParser *xmlParser;
NSMutableArray *getPartArr;
NSMutableDictionary *item;
NSString *currentElement;
NSMutableString *part_urlStr, *partNameStr;
}
#property (nonatomic,retain) NSMutableArray *getPartArr;
-(void) fetchPartXMLData:(NSInteger)empid:(NSInteger)serid:(NSInteger)seaid:(NSInteger)episodeid;
and in .m file :-
-(void) fetchPartXMLData:(NSInteger)empid:(NSInteger)serid:(NSInteger)seaid :(NSInteger)episodeid
{
NSURL *myURL = [NSURL URLWithString:#"http://webservices.asmx"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL: myURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
NSString *soapMessage = [NSString stringWithFormat:#"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
"<soap:Body>"
"<GetPart xmlns=\"http://tempuri.org/\">"
"<empid>%d</empid>"
"<serid>%d</serid>"
"<seaid>%d</seaid>"
"<episodeId>%d</episodeId>"
"</GetPart>"
"</soap:Body>"
"</soap:Envelope>",empid,serid,seaid,episodeid];
NSLog(#"soapMessage :%#",soapMessage);
[request addValue:#"text/xml; charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request addValue:#"http://tempuri.org/GetPart" forHTTPHeaderField:#"SOAPAction"];
NSString *msgLength = [NSString stringWithFormat:#"%d",[soapMessage length]];
[request addValue:msgLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPMethod: #"POST"];
[request setHTTPBody:[soapMessage dataUsingEncoding:NSUTF8StringEncoding]];
NSURLResponse *returnedResponse = nil;
NSError *returnedError = nil;
NSData *barData = [NSURLConnection sendSynchronousRequest:request returningResponse:&returnedResponse error:&returnedError];
NSString *barString = [[NSString alloc] initWithBytes:[barData bytes] length:[barData length] encoding:NSUTF8StringEncoding];
NSLog(#"barString :%#",[[barString stringByReplacingOccurrencesOfString:#"<" withString:#"<"] stringByReplacingOccurrencesOfString:#">" withString:#">"]);
NSData* data=[[[barString stringByReplacingOccurrencesOfString:#"<" withString:#"<"] stringByReplacingOccurrencesOfString:#">" withString:#">"] dataUsingEncoding:NSUTF8StringEncoding];
xmlParser = [[NSXMLParser alloc] initWithData:data];
[xmlParser setDelegate:self];
[xmlParser setShouldResolveExternalEntities:NO];
[xmlParser setShouldProcessNamespaces:NO];
[xmlParser setShouldReportNamespacePrefixes:NO];
[xmlParser parse];
}
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
getPartArr =[[NSMutableArray alloc] init];
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
NSString * errorString = [NSString stringWithFormat:#"Unable to download story feed from web site (Error code %i )", [parseError code]];
UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:#"Error loading content" message:errorString delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
{
currentElement = [elementName copy];
if ([elementName isEqualToString:#"part"])
{
item = [[NSMutableDictionary alloc] init];
part_urlStr = [[NSMutableString alloc]init];
partNameStr = [[NSMutableString alloc]init];
}
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if ([currentElement isEqualToString:#"part_url"])
{
[part_urlStr appendString:string];
}
if ([currentElement isEqualToString:#"partName"])
{
[partNameStr appendString:string];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"part"])
{
[item setObject:part_urlStr forKey:#"part_url"];
[item setObject:partNameStr forKey:#"partName"];
[getPartArr addObject:[item copy]];
}
NSLog(#"item dictionary....%#",partNameStr);
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
NSLog(#"getPartArr :%#",getPartArr);
}
it helps you and give what you want...
if you like then mark it as accepted
An event simpler way to get a ws result is:
NSString *urlString= [NSString stringWithFormat:#"http://demo.xyz.com/proj/webservices/display_records/1/%#%#%#",myid,name,password];
NSString *wsRes = [NSString stringWithContentsOfURL:urlStribng encoding: NSUTF8StringEncoding error:nil];
Consider extending this sample with error handling if you are going to use it.
I am trying to parse XML file which contains arabic words as follow:
<NewsComponent>
<HeadLine>العلاجية</HeadLine>
</NewsComponent>
when I NSLog the string on the NSXMLParser delegate it prints empty string, and even when i parse the data to the UITableView it shows empty text.
I am encoding the data as UTF-8 before passing it to the parser.
How can I parse the XMl without losing the content of the tag HeadLine?
notes:
1. The same XML with English language is working correctly.
2. Showing the XML in Any browser shows the data correctly.
3. converting the NSData to NSString and NSLog-ing before parsing the NSString show the xml correctly too.
Edit How am I doing this?
NSString *sURLREST = #"http://www.example.com/getXml";
NSURL *url = [NSURL URLWithString:sURLREST];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSURLResponse *response;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest: request returningResponse: &response error: &error];
NSString* output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSData* dataOutput = [output dataUsingEncoding: NSUTF8StringEncoding];
NSXMLParser *parser = [[NSXMLParser alloc] dataOutput];
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if([sCurrentItem isEqualToString:#"HeadLine"])
{
[mutuableArray addObject:string];
// I am just adding the string value to a NSMutuableArray to bind it with the UITableView.
NSLog(#"%#",string);
}
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
sCurrentItem = elementName;
}
Your error lies in parser:foundCharacters:. You cannot expect that that method will be called only once per element. It may be called multiple times. You have to create an empty mutable string before the method is called the first time per element (in parser:didStartElement:) and then append the new characters to that string. The string is not complete until parser:didEndElement: is called.
See Apple's sample code. They do it correctly.