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
Related
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.
I want to parse the html tags inside the "comparison" node
<comparison>
Amazon.com
($34.36) |
Walmart.com
($34.36) |
Rakuten.com
($34.36) |
BestBuy.com
($34.36)
</comparison>
The output I am getting is:
BestBuy.com ($34.36)
The expected output:
Amazon.com ($34.36)
Walmart.com ($34.36)
Rakuten.com ($34.36)
BestBuy.com ($34.36)
But I want to display all the four items.
CODE
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
currentElementValue = [NSMutableString string];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
if ([elementName isEqualToString:#"item"]) {
dealsListObj = [[DealsParsingObjects alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
[currentElementValue appendString:string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:#"short_title"]) {
dealsListObj.itemTitle = currentElementValue;
currentElementValue = nil;
}
else if ([elementName isEqualToString:#"final_price"]) {
dealsListObj.price = currentElementValue;
currentElementValue = nil;
}
//Detail view
else if ([elementName isEqualToString:#"merchant"]) {
dealsListObj.itemMerchant = currentElementValue;
currentElementValue = nil;
}
else if ([elementName isEqualToString:#"getdeal"]) {
dealsListObj.itemGetDeal = currentElementValue;
currentElementValue = nil;
}
//comparison
else if ([elementName isEqualToString:#"comparison"]) {
dealsListObj.comparison = currentElementValue;
currentElementValue = nil;
}
else if ([elementName isEqualToString:#"item"]) {
[resultArray addObject:dealsListObj];
[dealsListObj release];
dealsListObj = nil;
currentElementValue = nil;
}
}
It appears you have a DealsParsingObjects class with an NSMutableArray called commentsArray. You instantiate that array, when the parsing begins reading the <comparison> element.
But when the parser has read a <comparison> element, you assign the value to a property called comparison; it doesn't get added to the array. Being an default NSString property (assumption on my part), it simply gets reassigned each time the parser is done reading a <comparison> element.
Edit:
parser:didStartElement:... is called every time a new element is read. This also holds for the <a> tags. In that method you reset currentElementValue. So for each <a> the value is basically reset to an empty string. Only the last read value remains, which is the value of the last <a> tag plus the trailing text.
I have been trying to debug this error, and I can't find the issue. From what I have researched, I think that this is telling me that I am trying to release an object that has already been real eased, although I am not sure. I have a object that acts as the delegate for a NSXMLParser object, and I have a property of type NSMutableString that I use to hold the characters of each element. Here is my code:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
self.stringBuffer = [NSMutableString string];
if ([elementName isEqualToString:#"item"])
self.parsingPodcast = YES;
if (attributeDict)
self.currentAttributesDict = attributeDict;
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (string) [self.stringBuffer appendString:string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if (self.parsingPodcast)
{
if ([elementName isEqualToString:#"title"])
{
self.currentPodcastObject.title = self.stringBuffer;
}
else if ([elementName isEqualToString:#"pubDate"])
{
self.currentPodcastObject.publishDate = self.stringBuffer;
}
else if ([elementName isEqualToString:#"summary"])
{
self.currentPodcastObject.summary = self.stringBuffer;
}
else if ([elementName isEqualToString:#"imageurl"])
{
self.currentPodcastObject.imgURL = self.stringBuffer;
}
else if ([elementName isEqualToString:#"enclosure"])
{
self.currentPodcastObject.audioURL = [self.currentAttributesDict objectForKey:#"url"];
self.currentPodcastObject.audioType = [self.currentAttributesDict objectForKey:#"type"];
}
else if ([elementName isEqualToString:#"itunes:duration"])
{
self.currentPodcastObject.duration = self.stringBuffer;
}
else if ([elementName isEqualToString:#"item"])
{
parserCompletionBlock(self.currentPodcastObject);
}
}
}
I've enabled zombies in the scheme, and used the zombie tool to try and find any over released object, but I haven't been able to find anything. Here is the output on the console
:malloc: *** error for object 0x10e7531f0: double free
*** set a breakpoint in malloc_error_break to debug
I have added the malloc_error_break breakpoint
The breakpoint stops on the setter method for the self.stringBuffer property. Can anyone help me out? I must be missing something. Thanks in advance for your help!
[NSMutableString string] is autorelease. you should retain when assigning it on self.stringBuffer.
self.stringBuffer = [NSMutableString string] retain]
I actually got this error because the memory in my phone was almost full. Once i cleared some apps in my phone, the error went away. Not sure if this is useful, but it definitely helped me.
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 .
Ok so basically, I am trying to parse a sub-element:
<element>
<sub element 1>
<sub element 2>
<sub element 3>
<element>
The current original document that I want to parse contain as below for example:
sub-element-content1: AB, CD, DE, & SOMETHING DISPLAYED.
I only managed to grab & SOMETHING DISPLAYED. I could not parse the whole sub-element.
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
currentNodeContent = (NSMutableString *)[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
//NSLog(#"CURRENT CONTENT: %#", currentNodeContent);
}
That is the 1st issue. The second issue that I am having is that there are supposed to be 11 items in reference to the above. But it only managed to grab 2 items. Please note that each item contains the sub-elements except that some sub-elements are null
Issues has been added: (null)-(null)-(null)
Issues has been added: sub-element-1 sub-element2 sub-element3
Below is portion of didEndElement:
if ([elementName isEqualToString:#"Issue"]) {
//add currentIssue object into issues array
[issues addObject:currentIssue];
NSLog(#"Issues has been added: %#-%#-%#", currentIssue.sub-element-1, currentIssue.sub-element-2, currentIssue.sub-element-3);
currentIssue = nil;
currentNodeContent = nil;
}
if ([elementName isEqualToString:#"sub element 1"]) {
currentIssue.sub-element-1 = currentNodeContent;
NSLog(#"sub element 1: %#", currentIssue.sub-element-1);
}
if ([elementName isEqualToString:#"sub element 2"]) {
currentIssue.sub-element-2 = currentNodeContent;
NSLog(#"sub element 2: %#", currentIssue.sub-element-2);
}
if ([elementName isEqualToString:#"sub element 3"]) {
currentIssue.sub-element-3 = currentNodeContent;
NSLog(#"sub element 3: %#", currentIssue.sub-element-3);
}
Your advice(s) and/or suggestion(s) are greatly appreciated.
Update 1:
Ok, I have solved the problem.
It appears that "currentIssue = nil" causes the object to lose its contents as I was able to print out the currentNodeContent.
So, by removing, currentIssue, I am now able to see all the supposed elements that I need.
But there is one more problem. I can see all the sub elements now, but there only one sub element left which was grabbed partially which I do not understand why.
For <sub element 1> , sub element 1 is not the elementName . The element name is sub.
- (XMLParserViewController *) initXMLParser {
appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
return self;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict
{
if([elementName isEqualToString:#"Books"]) {
appDelegate.books = [[NSMutableArray alloc] init];
}
else if([elementName isEqualToString:#"Book"])
{
aBook = [[Books alloc] init];
}
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;
if([elementName isEqualToString:#"Book"])
{
[appDelegate.books addObject:aBook];
aBook = nil;
}
else if([elementName isEqualToString:#"name"])
{
aBook.name=currentElementValue;
}
else if([elementName isEqualToString:#"address"])
{
aBook.address=currentElementValue;
}
else if([elementName isEqualToString:#"country"])
{
aBook.country=currentElementValue;
}
currentElementValue = nil;
NSLog(#"%#",aBook.name);
NSLog(#"%#",aBook.address);
NSLog(#"%#",aBook.country);
}
Try this code eith your elements hope this works for you.... :)
Ok, I have solved the problem.
It appears that "currentIssue = nil" causes the object to lose its contents as I was able to print out the currentNodeContent.
So, by removing, currentIssue, I am now able to see all the supposed elements that I need.
Secondly, to make it work correctly, I initialized the array under "parserDidStartDocument" instead of "parserDidStartElement".