How to read a xml file in iOS - xml-parsing

I want to read a xml file within my iOS. Im reading it like this
NSURL *url = [[NSURL alloc] initWithString:urlString] ;
purchasedBookXMLParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
PurchasedBookXMLParser *bookParser = [[PurchasedBookXMLParser alloc] initPurchasedBookXMLParser];
[purchasedBookXMLParser setDelegate:bookParser];
BOOL success = [purchasedBookXMLParser parse];
But im getting success NO always. When I give the same url in browser I can see the xml data. What is the reason for this. How can I solve this. Please help me.
Thanks

Did u implement parser delegate method ??
In my project what i am doing is as below
NSURL *url = [NSURL URLWithString:#"https://api.sportsdatallc.org/nascar-p3/sc/2015/races/schedule.xml?api_key=wstdt33unpyk7sgpmjj5qver"];
parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[parser setDelegate:self];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
After that parser delegate methods call i.e. as below
If u want data between "race" tag then [element isEqualToString:#"race"]
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSString *element;
element = elementName;
if ([element isEqualToString:#"race"])
{
item2=[[NSMutableDictionary alloc] init];
[item2 setObject:attributeDict forKey:#"race"];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
[self.tableview reloadData];
}

Related

NSXMLParser - empty value

I am trying NSXMLParser for getting values from an XML for first time. But I have a problem.
Below my XML:
<Library>
<Book>
<ID>1</ID>
<TITLE>Test</TITLE>
</Book>
</Library>
and parser code:
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *) elementName namespaceURI:(NSString *)namespaceURI qualifiedNam(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if([elementName isEqualToString:#"Book"])
{
NSLog(#"%#", [attributeDict valueForKey:#"ID"]);
}
}
The result ID is null. Can you help me please?
Unfortunately, NSXMLParser doesn't work this way. It traverses over the elements in XML in document order, so by the time the "Book" element starts, it hasn't reached the "ID" element yet. Your code would work if the XML looked like
<Book Id="1">
...
</Book>
but I suppose you have no control over the XML. Then you need a more sophisticated solution. I believe the following would work:
Add these instance variables
NSString *currentElement, *bookID, *bookTitle;
NSMutableString *elementValue;
Implement the following methods:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *) elementName namespaceURI:(NSString *)namespaceURI qualifiedNam(NSString *)qName attributes:(NSDictionary *)attributeDict {
currentElement = elementName;
elementValue = nil;
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
// Append characters to element value
if (!elementValue) elementValue = [NSMutableString stringWithCapacity:100];
[elementValue appendString:string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName {
if ([#"Id" isEqualToString:elementName]) {
bookID = [elementValue copy];
} else if ([#"Title" isEqualToString:elementName]) {
bookTitle = [elementValue copy];
} else if ([#"Book" isEqualToString:elementName]) {
// end of Book element, do something with bookID and bookTitle
}
}
Follow the below code.You will understand.
In your .h part
//Step 1 : Add the Delegate classes
First of all you should add <NSXMLParserDelegate>
//Step 2 : Create necessary objects
NSXMLParser *parser;
NSMutableData *ReceviedData;
NSMutableString *currentStringValue;
NSMutableArray *arrayID;
In your .m part
//Step 3 - Allocate your all Arrays in your viewDidLoad method
arrayId = [NSMutableArray alloc]init];
//Step 4 - Create Connection in your viewDidLoad Like
[self createConnection:#"http://www.google.com"];//give your valid url.
-(void)createConnection:(NSString *)urlString
{
NSURL *url = [NSURL URLWithString:urlString];
//Step 5 - parser delegate methods are using NSURLConnectionDelegate class or not.
BOOL success;
if (!parser)
{
parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
parser.delegate = self;
parser.shouldResolveExternalEntities = YES;
success = [parser parse];
NSLog(#"Success : %c",success);
}
}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSLog(#"Current Element Name : %#",elementName);
if ([elementName isEqualToString:#"ID"])
{
NSLog(#"The Result is==%#",elementName);
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
currentStringValue = [[NSMutableString alloc] initWithString:string];
NSLog(#"Current String Value : %#",currentStringValue);
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"ID"])
{
[arrayResult addObject:currentStringValue];
}
currentStringValue = nil;
}

Parsing data with NSXML in iOS

I'm trying to parse data from a Wordpress RSS feed using NSXMLR. My problem is exporting my parsed data. So far I have,
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
currentElement = [elementName copy];
if ([elementName isEqualToString:#"item"]){
currentTitle = [[NSMutableString alloc] init];
item = [[NSMutableDictionary alloc] init];
}
}
this class
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"item"]){
[item setObject:currentTitle forKey:#"title"];
}
[stories addObject:item];
}
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if ([currentElement isEqualToString:#"title"]){
[currentTitle appendString:string];
}
}
NSMutableArray *stories;
NSMutableDictionary *item;
So in ViewDidLoad implementation, I have
//declare the object of allocated variable
NSData *xmlData=[[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:#"URL"]];// URL that given to parse.
//allocate memory for parser as well as
xmlParserObject =[[NSXMLParser alloc]initWithData:xmlData];
[xmlParserObject setDelegate:self];
//asking the xmlparser object to beggin with its parsing
[xmlParserObject parse];
NSLog(#"%#", [item objectForKey:#"title"]);
My problem is that I only print one object, I have multiples elements. How can I make it scan every single one of them and print them all.
Thanks in advance.
If I understand your code correctly, item holds the currently parsed item,
and the array stories holds all items.
So you have to allocate the stories array first:
stories = [[NSMutableArray alloc] init];
Then you do the parsing (but you should add an error check):
NSData *xmlData=[[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:#"URL"]];
xmlParserObject =[[NSXMLParser alloc]initWithData:xmlData];
[xmlParserObject setDelegate:self];
if (![xmlParserObject parse]) {
// Parsing failed, report error...
}
And finally print the contents of the array:
for (NSDictionary *story in stories) {
NSLog(#"%#", [story objectForKey:#"title"]);
}
The didEndElement method probably should look like this:
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"item"]){
[item setObject:currentTitle forKey:#"title"];
[stories addObject:item]; // <-- MOVED INTO THE IF-BLOCK
}
}

NSXML didStartElement method not being called

Iv'e set my h as the delegate and I'm calling the "setDelegate:self" method on my xml parser.
here is my code.
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
elementName = element;
if ([elementName isEqualToString:#"offer"]) {
offersDictionary = [[NSMutableDictionary alloc] init];
offerTitle = [[NSMutableString alloc] init];
offerDay = [[NSMutableString alloc] init];
offerDet = [[NSMutableString alloc] init];
NSLog(#"PARSER didStartElement method!");
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if ([element isEqualToString:#"offerTitle"]) {
[offerTitle appendString:string];
}
if ([element isEqualToString:#"day"]) {
[offerDay appendString:string];
}
if ([element isEqualToString:#"offerDetail"]) {
[offerDet appendString:string];
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:#"offer"]) {
[offersDictionary setObject:offerTitle forKey:#"offerTitle"]; NSLog(#"offerTitle:%#",offerTitle);
[offersDictionary setObject:offerDet forKey:#"offerDetail"]; NSLog(#"offerDet:%#",offerDet);
[offersDictionary setObject:offerDay forKey:#"day"]; NSLog(#"OfferDay:%#",offerDay);
NSLog(#"DidEndELEMENT");
//[offersArray addObject:[offersDictionary copy]];
}
}
I've set "NSlog" in my didStartElement and in my didEndElement methods, but I only get output from the didEndElement.
I'm calling the "parse" method of the NSXML from the viewDidLoad method.
here is my viewDidLoad method.
- (void)viewDidLoad
{
[super viewDidLoad];
//alloc and init the array
offersArray = [[NSMutableArray alloc] init];
//create NSUrl with the xml file
NSURL *xmlUrl = [NSURL URLWithString:#"http://mydomain.org/dir/dir/file.xml"];
//alloc and init the xml parser with the data of the file
xmlParser = [[NSXMLParser alloc]initWithContentsOfURL:xmlUrl];
//set some methods on the xml parser
[xmlParser setDelegate:self];
[xmlParser setShouldProcessNamespaces:NO];
[xmlParser setShouldReportNamespacePrefixes:NO];
[xmlParser setShouldResolveExternalEntities:NO];
//create a 'success gate' of the 'parse' method
BOOL xmlParseSuccess = [xmlParser parse];
if (xmlParseSuccess) {
NSLog(#"Successed Parsing! array Has %lu elements.", (unsigned long)offersArray.count);
} else if (!xmlParseSuccess) {
NSLog(#"Error Parsing!");
}
// Do any additional setup after loading the view.
}
Why is the didStartElement method not being called?
Here is your issue:
-(void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict {
/*
Your setting elementName to element. So whatever the
value of 'element' is, it will compare to #"offer".
It seems that the value of 'element' is not equal
to #"offer". You should not be Comment this line out
and it should work fine.
*/
elementName = element;
if ([elementName isEqualToString:#"offer"]) {
offersDictionary = [[NSMutableDictionary alloc] init];
offerTitle = [[NSMutableString alloc] init];
offerDay = [[NSMutableString alloc] init];
offerDet = [[NSMutableString alloc] init];
NSLog(#"PARSER didStartElement method!");
}
}

xml parsing having multiple opening tags

I m getting response like this
<NewDataSet>
<Map>
<URL>
https://maps.google.co.in/maps?q=ABIL+House,+Ganeshkhind+Road,+Yashwant+nagar,+Pune,+Maharashtra&hl=en&sll=18.539118,73.834095&sspn=0.011169,0.021136&oq=ABIL+House&t=h&hnear=ABIL+House,+2,+Ganeshkhind+Rd,+Yashwant+nagar,+Pune,+Maharashtra+411007&z=16
</URL>
</Map>
</NewDataSet>
I have to parse url value to show in web view. How to parse xml file having two opening tags, this is my code:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:#"Result"]) {
item = [[NSMutableDictionary alloc] init];
currentUser =[[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"Result"]) {
[item setObject:currentUser forKey:#"Result"];
// [item setObject:currentPassword forKey:#"Name"];
[users addObject:[item copy]];
}
}
- (void)parser:(NSXMLParser )parser foundCharacters:(NSString *)string
{
if ([currentElement isEqualToString:#"Result"]) {
[currentUser appendString:string];
}
/* if ([currentElement isEqualToString:#"Name"])
{
[currentPassword appendString:string];
}
*/
}
- (void)viewDidLoad
{
users = [[NSMutableArray alloc] init];
NSURL *xmlURL = [NSURL URLWithString:#"http://abilcms.com.sv2.premiumwebserver.com/WebServiceStatus.aspx?UserID=demo#abil.com"];
xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
[xmlParser setDelegate:self];
[xmlParser parse];
NSLog(#"name=%#",currentUser);
statuslabel.text= currentUser;
}
Here is a tutorial on xml parsing in ios that shows how it is done. http://theappcodeblog.com/2011/05/09/parsing-xml-in-an-iphone-app-tutorial
Here is another tutorial on accessing multi level XML documents
But as far as I can see you should just replace "Result" with "URL" if this is the only URL tag in your XML, as fa as I understand NSXMLParser will handle the levels for you in this case. Of course if there is more data in this XML that you need to access you should build it like the example in the second link.

How to parse data from a website using NSXMLParser

I want to get the updates from a website based on the titles and links which is in xml format.
I have tried with the code below but it's not working. In console it is showing the message:
2011-11-03 14:45:05.987 tabbar[673:e903] * Terminating app due to
uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFString
isEqualtostring:]: unrecognized selector sent to instance 0x5746830'
If I run again, the table view is loading but there is no data in the table cells.
It is showing this message at the line if ([elementName isEqualtostring:#"item"]):
program received signal SIGABRT
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
classelement = elementName;
if ([elementName isEqualtostring:#"item"])
{
itemselected = YES;
multitle = [[NSMutableString alloc]init];
mullink = [[NSMutableString alloc]init];
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedname:(NSString *)qName
{
if ([elementName isEqualToString:#"item"])
{
itemselected = NO;
[titlearray addObject:multitle];
[linkarray addObject:mullink];
[multitle release];
[mullink release];
[self.tbl reloadData];
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (itemselected)
{
if ([classelement isEqualToString:#"title"])
{
NSLog(#"%#",string);
[multitle appendString:multitle];
}
else if([classelement isEqualToString:#"link"])
{
[multitle appendString:string];
}
}
}
If you are reading directly from a website more than likely you are getting "invalid" characters. As soon as the parser see's these invalid characters it will crash. I would suggest looking at using "HPPLE Parser". It works much better and wont crash if invalid characters come in.
Hpple information here: http://blog.objectgraph.com/index.php/2010/02/24/parsing-html-iphone-development/
Finally I got it. What I did is I have taken two NSMutableArrays and two NSMutableStrings and I appended the items to the strings, and later those strings I appended to the two arrays.
(void)viewDidLoad
{
titlearray = [[NSMutableArray alloc]init];
linkarray = [[NSMutableArray alloc]init];
NSString *rssaddress =#"http://www.greenday.com/rss";
NSURL *url = [NSURL URLWithString:rssaddress];
xmlparser = [[NSXMLParser alloc]initWithContentsOfURL:url];
[xmlparser setDelegate:self];
[xmlparser parse];
[super viewDidLoad];
}
(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
classelement = elementName;
if([elementName isEqualToString:#"item" ])
{
itemselected = YES;
titlestrng = [[NSMutableString alloc]init];
linkstrng = [[NSMutableString alloc]init];
}
}
(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([elementName isEqualToString:#"item" ])
{
itemselected = NO;
[titlearray addObject:titlestrng];
[linkarray addObject:linkstrng];
[titlestrng release];
[linkstrng release];
[self.tb reloadData];
}
}
(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if(itemselected)
{
if([classelement isEqualToString:#"title"])
{
[titlestrng appendString: string];
NSLog(#"%#",titlestrng);
}
else if ([classelement isEqualToString:#"link"])
{
[linkstrng appendString:string];
NSLog(#"%#",linkstrng);
}
}
}

Resources