How to parse a locally stored XML file in iPhone?
please help me with this using code snippets
I have used NSXMLParser and i achieved it. I have r.xml file in my resource. I have just parsing the title and displayed using NSXMLParser.
r.xml:
<rss>
<eletitle > My Xml Program </eletitle>
</rss>
Here my sample code is,
#interface:
NSXMLParser *rssparser;
NSMutableArray *stories;
NSMutableDictionary *item;
NSMutableString *currrentTitle;
NSString *currentElement;
#implementation:
-(void) viewDidAppear:(BOOL) animated
{
[self parseXMLFileAtURL];
}
-(void) parseXMLFileAtURL
{
stories = [[NSMutableArray alloc] init];
NSURL *xmlURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"r" ofType:#"xml"]];
rssparser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
[rssparser setDelegate:self];
[rssparser setShouldProcessNamespaces:NO];
[rssparser setShouldReportNamespacePrefixes:NO];
[rssparser setShouldResolveExternalEntities:NO];
[rssparser parse];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
currentElement = [elementName copy];
if([elementName isEqualToString:#"rss"]);
{
item = [[NSMutableDictionary alloc] init];
currrentTitle = [[NSMutableString alloc] init];
}
}
-(void) parser:(NSXMLParser *)parser foundCharacters:(NSString *) string
{
if([currentElement isEqualToString:#"eletitle"])
{
[currrentTitle appendString:string];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if([elementName isEqualToString:#"rss"])
{
[item setObject:currrentTitle forKey:#"eletitle"];
[stories addObject:[item copy]];
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
NSLog(#"The currrentTitle is %#",currrentTitle);
}
Best of Luck.
I'm sorry I cannot give you any snippet now, but in one project I did some time ago, we used the touchXML library.
http://code.google.com/p/touchcode/wiki/TouchXML
With this, parsing XML was pretty easy.
Good luck!
Related
I have an xml like this, but my XMLParser jumps 1-2 elements, and not process it. I think it works fine, but it not. What do i wrong?
Here is the xml, and i'd like to get the all item tag, and it's child elements.
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>News</title>
<description>News - Android</description>
<link>http://www.p.com</link>
<item>
<title>World Bench Press highlights - Day 2</title>
<pubDate>Tue, 21 May 2013 00:00:00 +0000</pubDate>
<imgLink>http://www.powerlifting-ipf.com/typo3temp/pics/1b7ecb3ac3.jpg</imgLink>
<description>desc </description>
<URL> some URL </URL>
</item>
</channel>
</item>
</rss>
</channel>
Here is my XMLParser file, but i can't get any node, and it not put in my array. Not going to the
if ([elementname isEqualToString:#"item"])
#import <Foundation/Foundation.h>
#import "XMLParser.h"
#implementation XMLParser
#synthesize tweets = _tweets;
NSMutableString *currentNodeContent;
NSMutableString *copy;
NSXMLParser *parser;
Tweet *currentTweet;
bool isStatus=YES;
-(id) loadXMLByURL:(NSString *)urlString
{
_tweets = [[NSMutableArray alloc] init];
NSURL *url = [NSURL URLWithString:urlString];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
parser = [[NSXMLParser alloc] initWithData:data];
parser.delegate = self;
[parser parse];
NSLog(#"0");
return self;
}
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
NSLog(#"1");
NSLog(#"currentnode %#",currentNodeContent);
currentNodeContent = [[NSMutableString alloc] initWithCapacity:100];
[currentNodeContent appendString:string];
}
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSLog(#"2 Elementname : %#",elementname);
if ([elementname isEqualToString:#"item"])
{
currentTweet = [Tweet alloc];
isStatus = YES;
}
if ([elementname isEqualToString:#"title"])
{
NSLog(#"%#",currentNodeContent);
currentTweet.content = [NSString stringWithFormat:#"%# %#",currentTweet.content ,currentNodeContent];
}
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
NSLog(#"ELEMENT: %#",elementname);
if ([elementname isEqualToString:#"description"])
{
currentTweet.description = currentNodeContent;
}
if ([elementname isEqualToString:#"pubDate"])
{
currentTweet.dateCreated = currentNodeContent;
}
if ([elementname isEqualToString:#"title"])
{
currentTweet.title = currentNodeContent;
}
if ([elementname isEqualToString:#"imgLink"])
{
currentTweet.imgLink = currentNodeContent;
}
if ([elementname isEqualToString:#"URL"])
{
currentTweet.URL = currentNodeContent;
}
if ([elementname isEqualToString:#"item"])
{
NSLog(#"%# elem:",currentNodeContent);
[self.tweets addObject:currentTweet];
currentTweet = nil;
currentNodeContent = nil;
}
}
#end
Your approach is wrong because you are reallocating your mutable string every time that the XML parser finds new characters. This means that if you get a string like #"Hello", and the strings gets parsed into two separated string #"He" and #"llo", just #"llo" gets put into the mutable string. The correct approach is to allocate a new mutable string every time that you find a new tag, not when you find new characters.
Not sure because I am not aware of the whole context, but I would try to edit your first two methods this way:
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
NSLog(#"1");
NSLog(#"currentnode %#",currentNodeContent);
[currentNodeContent appendString:string];
}
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
currentNodeContent= [NSMutableString new];
NSLog(#"2 Elementname : %#",elementname);
if ([elementname isEqualToString:#"item"])
{
currentTweet = [Tweet alloc];
isStatus = YES;
}
}
Let me know what result you get. I also recommend putting breakpoints into every method to see (in the case) why you get some particular strings instead of expected results.
Edit
As for the XML, I tried to check it with xmllint, and it some errors. The problem is with these two extra lines after closing the channel tag:
</item> <!-- Not needed -->
</rss>
</channel> <!-- Not needed -->
You have one between and . Maybe that tag could be messing the parse procedure, try deleting it
I have already read about NSxmlparser. I have the following file, but I do not understand how I should do for the parser.
i Trying to parse xml list without parent node using NSxmlparser
<nodes1>
<child1>txt1</child1>
<child2>Txt2</child2>
</nodes1>
<nodes1>
<child1>Txt3</child1>
<child2>Txt4</child2>
</nodes1>
<nodes1>
<child1>Txt5</child1>
<child2>Txt6</child2>
</nodes1>
Get the file and start parsing
NSError *error;
NSString *xmlPath = [[NSBundle mainBundle] pathForResource:#"yourFile" ofType:#"xml"];
NSString* contents = [NSString stringWithContentsOfFile:xmlPath encoding:NSUTF8StringEncoding error:&error];
self.xmlData = [[NSData alloc] init];
self.xmlData = [contents dataUsingEncoding:NSUTF8StringEncoding];
self.xmlParser = [[NSXMLParser alloc] initWithData:self.xmlData];
[self.xmlParser setDelegate: self];
[self.xmlParser setShouldResolveExternalEntities: YES];
[self.xmlParser parse];
then for parsing
BOOL isValid_child1 = NO;
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *)qName attributes: (NSDictionary *)attributeDict
{
if ([elementName isEqualToString:#"child1"]) {
isValid_child1 = YES;
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (isValid_child1) {
valueInChild1 = string; // string is txt1
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"child1"]) {
isValid_child1 = NO;
[array addObject:valueInChild1]; // to add value for child1 to an array
}
I know this is dirty ;) but it works, you can do it more flexible.
<NewDataSet>
<Table>
<CaseId>743</CaseId>
<PartyId>11100550</PartyId>
<CartId>18</CartId>
</Table>
<Table>
<CaseId>742</CaseId>
<PartyId>11100549</PartyId>
<CartId>1148</CartId>
<BusinessID>19</BusinessID>
</Table>
</NewDataSet>
NSData* data = [xmlResponseData dataUsingEncoding:NSUTF8StringEncoding];
// NSXMLParser *XMLparser = [[NSXMLParser alloc] initWithData:data];
// [XMLparser setDelegate:self];
BOOL success;
if (XMLparser) // addressParser is an NSXMLParser instance variable
[XMLparser release];
XMLparser = [[NSXMLParser alloc] initWithData:data];
[XMLparser setDelegate:self];
[XMLparser setShouldResolveExternalEntities:YES];
success = [XMLparser parse]; // return value not used
// if not successful, delegate is informed of error
if(success)
NSLog(#"Sucess Parsed");
else
NSLog(#"Error Error Error!!!");
// NSLog(#"Parsed string : %#",valueForItem);
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {
if([elementName isEqualToString:#"NewDataSet"]) {
caseID_List = [[NSMutableArray alloc]init];
}
NSLog(#"Processing Element: %#", elementName);
if ([elementName isEqualToString:#"CaseId"]) {
}
}
- (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:#"NewDataSet"])
return;
}
I need only CaseId to store from the given xml. Can any one advice me on this simple parsing!
For me its looping! and getting all details
Use the Below Code.Where Table is NSObject Class with the CaseId,PartyId,CartId as a properties in this class.If you have the xml url just called loadXMLByURL method with URl.After parsing you will get Each Object in TableArray which have the Table object with above properties.
NSMutableString *currentNodeContent;
NSXMLParser *parser;
Tweet *currentTweet;
bool isStatus;
-(id) loadXMLByURL:(NSString *)urlString
{
_tweets = [[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:#"Table"])
{
currentTable = [Table alloc];
isStatus = YES;
}
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if (isStatus)
{
if ([elementname isEqualToString:#"CaseId"])
{
currentTable.CaseId = currentNodeContent;
}
if ([elementname isEqualToString:#"PartyId"])
{
currentTable.PartyId = currentNodeContent;
}
if ([elementname isEqualToString:#"CartId"])
{
currentTable.CartId = currentNodeContent;
}
}
if ([elementname isEqualToString:#"Table"])
{
[self.tableArray addObject:currentTable];
currentTable = nil;
currentNodeContent = nil;
}
}
Let me know if you have any doubt.
I am following the below link to parse the xml for login page, http://yksoftware.blogspot.in/2010/04/iphone-programming-tutorial-xml-login.html
whenever i enter the fields of username and password, it displays login failed only even when i provide the correct username and password in the textfields.
In the following code when i keep the breakpoint in loginPressed method and check, it is not entering the for loop,
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
users = [[NSMutableArray alloc]init];
NSURL *xmlURL = [NSURL URLWithString:#"http://www.mailrail.net/sample.aspx?username=naresh&password=reddy"];
xmlParser = [[NSXMLParser alloc]initWithContentsOfURL:xmlURL];
[xmlParser setDelegate:self];
[xmlParser parse];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
currentElement = [elementName copy];
if ([elementName isEqualToString:#"User"]) {
item = [[NSMutableDictionary alloc] init];
currentUser =[[NSMutableString alloc] init];
currentPassword =[[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"User"]) {
[item setObject:currentUser forKey:#"username"];
[item setObject:currentPassword forKey:#"password"];
[users addObject:[item copy]];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if ([currentElement isEqualToString:#"username"]) {
[currentUser appendString:string];
}
if ([currentElement isEqualToString:#"password"]) {
[currentPassword appendString:string];
}
}
-(IBAction)loginPressed:(id)sender{
for (NSMutableDictionary *val in users) {
NSMutableString *usrname = [val objectForKey:#"username"];
NSLog(#"%#",usrname);
NSMutableString *psswrd = [val objectForKey:#"password"];
usrname=[usrname stringByReplacingOccurrencesOfString:#"\n" withString:#""];
usrname=[usrname stringByReplacingOccurrencesOfString:#"\t" withString:#""];
psswrd=[psswrd stringByReplacingOccurrencesOfString:#"\n" withString:#""];
psswrd=[psswrd stringByReplacingOccurrencesOfString:#"\t" withString:#""];
if([usrname isEqualToString:[txtUsername text]]&&[psswrd isEqualToString:[txtPassword text]]){
[lblLoginStatus setText:#"Login Successful!!"];
return;
}
}
[lblLoginStatus setText:#"login failed"];
return;
}
-(IBAction)returnClicked:(UITextField *)sender{
[sender resignFirstResponder];
}
-(IBAction)clickBackground:(id)sender{
[txtPassword resignFirstResponder];
[txtUsername resignFirstResponder];
}
and returns with login failed.
Thanks in advance.
You first need to solve the parsing how to parse some thing from xml using parser and then think for loging beacuse if you have made parser then it is easy to use login form. Below is the following tutorial for XML parsing it is detailed and help you can get help.
http://www.edumobile.org/iphone/iphone-programming-tutorials/parsing-an-xml-file/
hope this helps
Just check this
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
currentElement = [elementName copy];
if ([elementName isEqualToString:#"User"]) {
NSMutableDictionary *item = [[NSMutableDictionary alloc] init];
[item setValue:[attributeDict valueForKey:#"username"] forKey:#"username"];
[item setValue:[attributeDict valueForKey:#"password"] forKey:#"password"];
[users addObject:item];
}
}
please del other two delegates and check this
i have to parse an xml and the link of that xml is
http://qasimshah.sitesled.com/schedule.xml
and may to parse is:
-(IBAction)autoLoginBtn{
NSString *url=[NSString stringWithFormat: #"http://qasimshah.sitesled.com/schedule.xml"];
[self parseXMLFileAtURL:url];
}
- (void)parseXMLFileAtURL:(NSString *)URL
{
xmlDataArray1 = [[NSMutableArray alloc] init];
//you must then convert the path to a proper NSURL or it won't work
NSURL *xmlURL = [NSURL URLWithString:URL];
// here, for some reason you have to use NSClassFromString when trying to alloc NSXMLParser, otherwise you will get an object not found error
// this may be necessary only for the toolchain
NSXMLParser *rssParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
// Set self as the delegate of the parser so that it will receive the parser delegate methods callbacks.
[rssParser setDelegate:self];
// Depending on the XML document you're parsing, you may want to enable these features of NSXMLParser.
[rssParser setShouldProcessNamespaces:NO];
[rssParser setShouldReportNamespacePrefixes:NO];
[rssParser setShouldResolveExternalEntities:NO];
[rssParser parse];
}
-(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{
NSLog(#"Error on XML Parse: %#", [parseError localizedDescription] );
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
//NSLog(#"found this element: %#", elementName);
currentElement = [elementName copy];
if ([elementName isEqualToString:#"Sports"]) {
// clear out our story item caches...
item = [[NSMutableDictionary alloc] init];
currentTitle = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"Sport"]) {
[item setObject:currentTitle forKey:#"id"];
[xmlDataArray1 addObject:[item copy]];
NSLog(#"id: %#", currentTitle);
}
}
but when i try to get 'id' or name parser detect it but do not return me its value.
so how can i get its value?
You should get the attribute value in "attributeDict"
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
you are only referring element ...
Try this. You can get all the values like this.
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict
{
if([elementName isEqualToString:#"Sport"])
{
NSString *s = [NSString stringWithFormat:#"%#",elementName];
NSLog(#"%#",s);
NSString *s1 =[NSString stringWithFormat:#"%#",[attributeDict valueForKey:#"id"]];
NSLog(#"%#",s1);
NSString *s2 =[NSString stringWithFormat:#"%#",[attributeDict valueForKey:#"name"]];
NSLog(#"%#",s2);
NSString *s3 =[NSString stringWithFormat:#"%#",[attributeDict valueForKey:#"abbr"]];
NSLog(#"%#",s3);
}
}
In didStartElement: you're checking for "Sports" but in didEndElement: you're checking for "Sport"...