How can I parse this xml in iOS 7? - ios

I want to parse this XML:
<?xml version="1.0" encoding="UTF-8"?>
<eventdata>
<rev></rev>
<event>
<id> </id>
<name></name>
<thumb> </thumb>
<eimage></eimage>
<artists></artists>
<date></date>
<time> </time>
<cost> </cost>
<discount> </discount>
<gmap> </gmap>
<web> </web>
<desc> </desc>
<file>
<src> </src>
<size> </size>
</file>
<vtype></vtype>
<address></address>
<area></area>
<city></city>
<pcode></pcode>
<lmark></lmark>
<likes></likes>
<hl></hl>
<pref></pref>
<img> <src> </src>
<size> </size></img>
<vid> <src> </src>
<size> </size></vid>
</event>
<event>
<id> </id>
<name></name>
<thumb> </thumb>
<eimage></eimage>
<artists></artists>
<date></date>
<time> </time>
<cost> </cost>
<discount> </discount>
<gmap> </gmap>
<web> </web>
<desc> </desc>
<file>
<src> </src>
<size> </size>
</file>
<vtype></vtype>
<address></address>
<area></area>
<city></city>
<pcode></pcode>
<lmark></lmark>
<likes></likes>
<hl></hl>
<pref></pref>
<img> <src> </src>
<size> </size></img>
<vid> <src> </src>
<size> </size></vid>
</event>
</eventdata>
I tried this code:
- (void)viewDidLoad
{
[super viewDidLoad];
_currentParsedCharacterData = [[NSMutableString alloc] init];
NSString *path = [[NSBundle mainBundle] pathForResource:#"NewYearPartyData" ofType:#"xml"];
NSData *data = [[NSData alloc] initWithContentsOfFile:path];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
[parser setDelegate:self];
// parsing...
BOOL success = [parser parse];
// test the result
if (success) {
//NSLog(#"No errors - user count : %i", [parser [users count]]);
NSLog(#"Success");
// get array of users here
// NSMutableArray *users = [parser users];
} else {
NSLog(#"Error parsing document!");
}
}
#pragma mark - NSXMLParser delegate methods
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
if ([elementName isEqualToString:#"event"]) {
NSLog(#"user element found – create a new instance of User class...");
//user = [[User alloc] init];
//We do not have any attributes in the user elements, but if
// you do, you can extract them here:
// user.att = [[attributeDict objectForKey:#"<att name>"] ...];
NSLog(#"Event Name = %#", [attributeDict objectForKey:#"name"]);
NSLog(#"attributeDict = %#", attributeDict);
}
if ([elementName isEqualToString:#"name"]) {
NSLog(#"attributeDict = %#", attributeDict);
NSLog(#"Event Name = %#", [attributeDict objectForKey:#"name"]);
NSLog(#"elementName = %#", elementName);
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
NSLog(#"didEndElement");
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
NSLog(#"value of element %#", string);
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
}
Someone who is good in NSXMLParser - I request them to explain to me the flow.
My basic question is "How to access data of event i.e., id, name, thumb etc?"

NSXMLParsing is the easiest way to parse data. You can easily access data of event i.e., id, name, thumb etc using the delegate method
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
}
You can create a NSOBject class named Event.
Here is my code
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementname isEqualToString:#"id"])
{
event.id = currentNodeContentChapters;
}
if ([elementname isEqualToString:#"name"])
{
event.name = currentNodeContentChapters;
}
if ([elementname isEqualToString:#"thumb"])
{
event.thumb = currentNodeContentChapters;
}
if ([elementname isEqualToString:#"eiimage"])
{
event.eiimageUrl = currentNodeContentChapters;
}
-------------------
---------------
}
Hopefully it will work for you .

Related

XML file parsing delegate issues

i have xml file to which i'm parsing through the delegates method of NSXML parser. I have three delegates method didStart , FoundCharacters and didEndElement. When i parse the file and when it goes in found characters method it shows me all the string data from xml file in console, but i'm trying to take only the given tag data value. Its showing me all the string data from xml file . My xml file is this,
<?xml version="1.0" encoding="UTF-8"?>
<QF id="AB2001" topic="Alertness" category="C&M" ni_exempt="no">
<question>
<xref>DES s4, DES s9, HC r159-161</xref>
<text>Before you make a U-turn in the road, you should</text>
<graphic></graphic>
<prompt>Mark one answer</prompt>
<voice id="AB2001-1"/>
<explanation>
<text>If you want to make a U-turn, slow down and ensure that the road is clear in both directions. Make sure that the road is wide enough to carry out the manoeuvre safely.</text>
<voice id="AB2001-2"/>
</explanation>
</question>
<answers>
<answer correct="no">
<text>give an arm signal as well as using your indicators</text>
<graphic></graphic>
</answer>
<answer correct="no">
<text>signal so that other drivers can slow down for you</text>
<graphic></graphic>
</answer>
<answer correct="yes">
<text>look over your shoulder for a final check</text>
<graphic></graphic>
</answer>
<answer correct="no">
<text>select a higher gear than normal</text>
<graphic></graphic>
</answer>
</answers>
The methods are these through which i'm parsing,
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *)qName
attributes: (NSDictionary *)attributeDict
{
if([elementName isEqualToString:#"QF"]) {
NSLog(#"ID %#",[attributeDict objectForKey:#"id"]);
NSLog(#"Topic %#",[attributeDict objectForKey:#"topic"]);
}
if( [elementName isEqualToString:#"question"])
{
_foundValue = [[NSMutableString alloc] init];
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
// Store the found characters if only we're interested in the current element.
if([_currentElement isEqualToString:#"xref"]){
// init the ad hoc string with the value
_currentElement = [[NSMutableString alloc] initWithString:string];
NSLog(#"Hello");
} else {
// append value to the ad hoc string
[_currentElement stringByAppendingString:string];
NSLog(#"Hi");
}
NSLog(#"Processing value for : %#", string);
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if( [elementName isEqualToString:#"QF"])
{
[_foundValue setString:elementName];
NSLog(#"rr %#",_foundValue);
}
if( [elementName isEqualToString:#"xref"])
{
[_foundValue setString:elementName];
}
_currentElement = nil;
}
In console i'm getting all the string data, from and even from answer tag but i haven't given that tag to parse. I'm confused that why it isn't getting value from the tag which i have given?
If I am understanding correctly what you want (to get xref element's value), first declare a NSMutableString* tmpString to which you will append xref's value in foundCharacters method. Then this should do it:
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *)qName attributes: (NSDictionary *)attributeDict
{
_currentElement = [[NSMutableString alloc]initWithString:elementName];
if([elementName isEqualToString:#"QF"]) {
NSLog(#"ID %#",[attributeDict objectForKey:#"id"]);
NSLog(#"Topic %#",[attributeDict objectForKey:#"topic"]);
}
if( [elementName isEqualToString:#"xref"])
{
_tmpString = [[NSMutableString alloc] init];
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if([_currentElement isEqualToString:#"xref"]){
[_tmpString appendString:string];
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if( [elementName isEqualToString:#"QF"])
{
[_foundValue setString:elementName];
}
if( [elementName isEqualToString:#"xref"])
{
NSLog(#"xref %#",_tmpString);
[_foundValue setString:elementName];
}
_currentElement = nil;
}
Output is:
ID AB2001
Topic Alertness
xref DES s4, DES s9, HC r159-161
FoundCharacters method is one capturing text between start and end tag of an element. So we keep track of current element, and if it is element we are interested in, we get its text inside foundCharacters method.

NSXMLParser not finding closing tag

Im trying to fetch list of content from xml web source . Im using NSXMLParser atm.
here is the code :
- (void)main
{
self.workingArray = [NSMutableArray array];
self.workingPropertyString = [NSMutableString string];
NSURL *url = [[NSURL alloc]initWithString:#"http://myxmlwebsite.xml"];
NSXMLParser *parser = [[NSXMLParser alloc]initWithContentsOfURL:url];
[parser setDelegate:self];
bool result = [parser parse];
NSLog(#"result is ok for xml parse : %#", result ? #"Yes" : #"No");
if (![self isCancelled])
{
self.appRecordList = [NSArray arrayWithArray:self.workingArray];
SubCategoryViewController *subCategoryViewController;
subCategoryViewController.entries = self.appRecordList;
[subCategoryViewController.tableView reloadData];
}
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:kUser])
{
self.workingEntry = [[UserFetchAppRecord alloc] init];
}
_elementsToParse = [[NSArray alloc] initWithObjects:
kid,ktitle, nil];
self.storingCharacterData = [_elementsToParse containsObject:elementName];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
if (self.workingEntry)
{
if (self.storingCharacterData)
{
NSString *trimmedString = [self.workingPropertyString stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[self.workingPropertyString setString:#""];
if ([elementName isEqualToString:kid])
{
self.workingEntry.ids = trimmedString;
NSLog(#"id : %#" , trimmedString);
}
else if ([elementName isEqualToString:ktitle])
{
self.workingEntry.title = trimmedString;
NSLog(#"ktitle : %#" , trimmedString);
}
}
else if ([elementName isEqualToString:kUser])
{
NSLog(#"inside elementName isEqualToString:kUser");
[self.workingArray addObject:self.workingEntry];
NSUInteger self_workingArrayCount = [self.workingArray count];
self.workingEntry = nil;
}
}
}
Now at console if i run program i get these results :
"result is ok for xml parse = true"
"id : 1"
"ktitle : usertitle"
.
.
.
but the result of closing tab no showing in console, this one "inside elementName isEqualToString:kUser".
hows that possible ?
the tag of my xml are like this :
<Main>
<user>
<id></id>
<title></title>
</user>
<user>
<id></id>
<title></title>
</user>
.....
</Main>
Change else if ([elementName isEqualToString:kUser]) in
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
to if ([elementName isEqualToString:kUser]).
self.storingCharacterData become YES when element id or title starts. So when element user ends self.storingCharacterData will be YES, and else if ([elementName isEqualToString:kUser]) wont work.

Objective-C:How to read an attribute value in XML

Hi friends am new to iphone app developing. Actually i have to parse XML file and have display it in a tableviewcontroller. Am using storyboards. i have parsed Xml successfully and parsed data and displayed it. But i cannot able to read this attribute <Event count="-1"> i have read this value and have to display it on the tab bar i have to set badge value as -1
Pls help me How to do it. Thanks in advance.. Here is my Xml file
<boards>
<board count="-1">
<newboard>
<id>9</id>
<invitationdet>qweq</invitationdet>
<readflag>1</readflag>
<responseflag>1</responseflag>
</newboard>
<newboard>
<id>8</id>
<invitationdet>asd</invitationdet>
<readflag>1</readflag>
<responseflag>1</responseflag>
</newboard>
</board>
<back count="0">
<backboard>
<id>2</id>
<feedbackdet>Meeting with Clients</feedbackdet>
<readflag>1</readflag>
<responseflag>0</responseflag>
</backboard>
<backboard>
<id>1</id>
<feedbackdet>Board Meeting with employees</feedbackdet>
<readflag>1</readflag>
<responseflag>0</responseflag>
</backboard>
</back>
<letter count="3">
<newletter>
<id>4</id>
<letterdet>NewsLetter for the month of October 2013</letterdet>
<readflag>1</readflag>
</newletter>
<newletter>
<id>3</id>
<letterdet>Newsletter for the month of September 2013</letterdet>
<readflag>0</readflag>
</newletter>
<newletter>
<id>2</id>
<letterdet>Newsletter for the month of August 2013</letterdet>
<readflag>0</readflag>
</newletter>
<newletter>
<id>1</id>
<letterdet>Newsletter For the month of July 2013</letterdet>
<readflag>0</readflag>
</newletter>
</letter>
</boards>
And Here is my XMLParser File
-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
if([elementName isEqualToString:#"boards"]) {
rssOutputData = [[NSMutableArray alloc] init];
}
if([elementName isEqualToString:#"board"]) {
//Initialize the array.
aEvent.count = [attributeDict objectForKey:#"count"];
NSLog(#"Reading count value :%#", aEvent.count);
}
else if([elementName isEqualToString:#"newboard"]) {
//Initialize the book.
aEvent = [[Eventlist alloc] init];
//Extract the attribute here.
aEvent.id = [[attributeDict objectForKey:#"userid"] integerValue];
NSLog(#"Reading id value :%d", aEvent.id);
}
NSLog(#"Processing Element: %#", elementName);
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if(!nodecontent)
nodecontent = [[NSMutableString alloc] initWithString:string];else
[nodecontent appendString:string];
NSLog(#"Processing Value: %#", nodecontent);
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if([elementName isEqualToString:#"boards"])
return;
if([elementName isEqualToString:#"board"])
return;
if([elementName isEqualToString:#"newboard"]) {
[rssOutputData addObject:aEvent];
[aEvent release];
aEvent= nil;
}
else
[aEvent setValue:nodecontent forKey:elementName];
[nodecontent release];
nodecontent = nil;
}
I can read datas correctly but i cannot able to read Attribute values pls help me friends
Try like the below
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict
{
// just do this for item elements
if(![elementName isEqual:#"letter"])
return;
// then you just need to grab each of your attributes
int count = [attributeDict objectForKey:#"count"];
}
In the following method you have noticed that, there is a parameter attributeDict which holds all the attributes of tag
-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
if([attributeDict valueForKey:#"count"]) {
NSLog(#"%#", [attributeDict valueForKey:#"count"]);
}
}
You can read it as defined in the above code. just log whole attributeDict and you will get your answer. - Good Luck

How to parse SOAP xml response in iPhone programming

I am unable to parse soap response,I have tried many ways but not solved my problem,I need the value of USERNAME and PASSWORD.
I am getting following response after soap request :
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<AuthenticateResponse xmlns="http://tempuri.org/">
<AuthenticateResult>
<DocumentElement>
<Status>
<USERNAME>True</USERNAME>
<PASSWORD>true</PASSWORD>
</Status>
</DocumentElement>
</AuthenticateResult>
</AuthenticateResponse>
</soap:Body>
</soap:Envelope>
Here is my code :
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *)qName attributes: (NSDictionary *)attributeDict
{
if ( [elementName isEqualToString:#"AuthenticateResponse"]||[elementName
isEqualToString:#"AuthenticateResult"] || [elementName isEqualToString:#"DocumentElement"])
{
statusArray = [[NSMutableArray alloc] init];
}
else if ([elementName isEqualToString:#"Status"])
{
authenticate = [[Authenticate alloc] init];
}
else if ([elementName isEqualToString:#"USERNAME"])
{
currentElementValue = [[NSMutableString alloc] init];
}
else if ([elementName isEqualToString:#"PASSWORD"])
{
currentElementValue = [[NSMutableString alloc] init];
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (currentElementValue)
{
[currentElementValue appendString:string];
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI: (NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if( [elementName isEqualToString:#"USERNAME"])
{
authenticate.userName = currentElementValue;
}
else if ([elementName isEqualToString:#"PASSWORD"])
{
authenticate.strAuthenticate = currentElementValue;
}
else if ([elementName isEqualToString:#"Status"]) {
[statusArray addObject:authenticate];
}
}
How can i get the values of username and password,can someone help me to parse this.
Thanks in advance.
Try this:
Add 2 properties to your class.
#property (nonatomic, strong) NSString *elementValue;
#property (nonatomic, strong) NSMutableArray *authenticationValues;
Replace your current implementation by:
- (void)parseXML:(NSData *)xmlData {
self.authenticationValues = [NSMutableArray array];
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:xmlData];
parser.delegate = self;
[parser parse];
NSLog(#"Authentication values: %#", self.authenticationValues);
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
// Keep track of the current element value
self.elementValue = string;
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
// If the element was 'username' or 'password', add the value to the authenticationValues array
if ([elementName isEqualToString:#"USERNAME"] ||
[elementName isEqualToString:#"PASSWORD"]) {
[self.authenticationValues addObject:self.elementValue];
}
}
To parse the file perform the method parseXML:
When running this you should see the following output on the console:
Authentication values: (
True,
true
)
which are the values for USERNAME and PASSWORD.
Please see the demo prepared for iOS/OSX using sample web service.
It uses swift - SOAP request creator & response parser.
[DEMO][1]
Done using Alamofire & SWXMLHash library
Thanks

NSXMLParser strange behavior with \n

I'm developing an iOS 4 application that parses a XML file. A piece of XML is:
<?xml version="1.0" encoding="utf-8" ?>
<cards>
<card id ="0">
<name lang="es">The Mad</name>
<description lang="es">...</description>
</card>
...
</cards>
I use the following method to parse <name lang="es">The Mad</name>.
#pragma mark -
#pragma mark NSXMLParserDelegate methods
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict
{
NSLog(#"DidStartElement: %#", elementName);
if ([elementName isEqualToString:#"card"])
{
currentCard = [[Card alloc] init];
NSString* arcaneNumber = [attributeDict objectForKey:#"id"];
currentCard.Number = arcaneNumber;
return;
}
if ([elementName isEqualToString:#"name"])
{
if ([[attributeDict objectForKey:#"lang"] isEqualToString:userLanguage])
{
currentProperty = kNameProperty;
return;
}
}
if ([elementName isEqualToString:#"description"])
{
if ([[attributeDict objectForKey:#"lang"] isEqualToString:userLanguage])
{
currentProperty = kDescriptionProperty;
return;
}
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (!currentStringValue)
{
// currentStringValue is an NSMutableString instance variable
currentStringValue = [[NSMutableString alloc] initWithCapacity:50];
}
[currentStringValue appendString:string];
}
- (void) parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
NSLog(#"DidEndElement: %#", elementName);
if ([elementName isEqualToString:#"card"])
{
[cards setObject:currentCard forKey:currentCard.Number];
[currentCard release];
currentCard = nil;
return;
}
if (currentProperty == kNameProperty)
{
currentProperty = kNoneProperty;
currentCard.Name = [currentStringValue stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[currentStringValue release];
currentStringValue = nil;
return;
}
if (currentProperty == kDescriptionProperty)
{
currentProperty = kNoneProperty;
currentCard.Description = currentStringValue;
[currentStringValue release];
currentStringValue = nil;
return;
}
}
After, parsing , I get on currentStringValue the following:
\n\nThe Mad
How can avoid these two '\n'? Why am I getting these two '\n'?
This xml file came from a Windows system, and I've used TextWrangler to covert it to Classic Mac format.
The foundCharacters delegate method also gets called for whitespace in between elements. It will get called if there is say a newline between <cards> and <card id=....
I suggest clearing currentStringValue at the top of didStartElement to discard any characters found before the start of the current element and to make sure only the characters inside the current element (not between) are captured by foundCharacters.
At the top of didStartElement, add:
[currentStringValue release];
currentStringValue = nil;
It is possible for an element's value to contain whitespace (so removing them in didEndElement could result in saving values that don't match the xml content).
On your end element method you can try stripping these out yourself from the current text string. Simply try searching for them on the string and replace them with #"". I like replacing these and unwanted blank entries.
Try this it work for me ,
NSString *data= [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
Use above line of code in foundCharacters method .
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;
{
NSString *data= [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if(dString == nil){
dString = [[NSMutableString alloc] initWithString:data];
}else
{
[dString appendString:data];
}
}
Hope this will help for some one .

Resources