elements in XML parsing - iphone

I am new in iphone Development, I don't know much about parsing. But I tried following code to get the distance element text. I am doing XMl parsing Of following link:
http://maps.googleapis.com/maps/api/directions/xml?origin=30.9165904,75.8634752&destination=30.89314000,75.86938000&sensor=true
Please check my code which i have tried:
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:
(NSDictionary *)attributeDict
{
currentElement = [elementName copy];
if([currentElement isEqualToString:#"distance"])
{
NSLog(#"ENTER IN distance");
text = [[NSMutableString alloc]init];
{
dictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:text,#"text",nil];
}
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if ([currentElement isEqualToString:#"text"])
{
[dictionary setObject:text forKey:currentElement];
[text appendString:string];
NSLog(#"text....%#",text);
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:
(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"distance"])
{
[distanparsingarray addObject:dictionary];
}
}
By using above method I am getting the text both of distance and duration. But I want only distance text. Please tell me what I am doing wrong in above code.
thanks in advance.

You have to manage it by below way.
Add on BOOL variable at class level. Set it when you identify currentElement as distance.
Inside found characters append string to text only when above BOOL is true.
Make this BOOL as false in didEndElement when currentElement is not equal to distance.
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:
(NSDictionary *)attributeDict
{
currentElement = [elementName copy];
if([currentElement isEqualToString:#"distance"])
{
flag = TRUE; //created at class level.
NSLog(#"ENTER IN distance");
text = [[NSMutableString alloc]init];
{
dictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:text,#"text",nil];
}
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if ([currentElement isEqualToString:#"text"] && flag == TRUE)
{
[dictionary setObject:text forKey:currentElement];
[text appendString:string];
NSLog(#"text....%#",text);
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:
(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"distance"])
{
[distanparsingarray addObject:dictionary];
flag = FALSE;
}
}

Related

XML Parse not showing elements with & symbol inside

Im trying to parse a xml feed in my app... The xml file is in this url
feeds.feedburner.com/blogspot/TUvAW?format=xml
The problem is that when I access the description segment it diplays different special symbols such as quotation marks. This is one of the descripton segments im trying to parse from my xml:
<description>Este es mi blog 3<img src="http://feeds.feedburner.com/~r/blogspot/TUvAW/~4/URCV9ModTR0" height="1" width="1"/></description>
Im parsing it with the NSXMLParser, these are the method I'm using in my:
XMLParser.m
- (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:#"item"])
{
currentFeed = [Feed alloc];
isStatus = YES;
}
if ([elementname isEqualToString:#"author"])
{
isStatus = NO;
}
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if (isStatus)
{
if ([elementname isEqualToString:#"description"])
{
currentFeed.description = currentNodeContent;
NSLog(#"%#",currentNodeContent);
}
if ([elementname isEqualToString:#"title"])
{
currentFeed.content = currentNodeContent;
NSLog(#"%#",currentNodeContent);
}
if ([elementname isEqualToString:#"link"])
{
currentFeed.WVUrl = currentNodeContent;
NSLog(#"%#",currentNodeContent);
}
}
if ([elementname isEqualToString:#"item"])
{
[self.feeds addObject:currentFeed];
currentFeed = nil;
currentNodeContent = nil;
}
}
Im using those NSLogs to track the strings that Im getting from the parse but my description node content is always showing just this : >
The title and link nodes are displaying perfectly.
I want to get all that string from the description node to use it later but simply I can't, I dont know whats going wrong with this.
The problems have been outlined by Abhishek, Rob and me. But I think it's worth to summarize it and show the correct solution.
The main problem is that parser:foundCharacters: is called several times for the <description> tag, each call providing a piece of the description.
The solution is to concatenate the pieces:
XMLParser.h:
NSMutableString* currentNodeContent;
XMLParser.m:
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (currentNodeContent == nil)
currentNodeContent = [[NSMutableString alloc] initWithCapacity: 20];
[currentNodeContent appendString: [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
}
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementname isEqualToString:#"item"])
{
currentFeed = [Feed alloc];
isStatus = YES;
}
if ([elementname isEqualToString:#"author"])
{
isStatus = NO;
}
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if (isStatus)
{
if ([elementname isEqualToString:#"description"])
{
currentTweet.description = currentNodeContent;
NSLog(#"%#",currentNodeContent);
}
if ([elementname isEqualToString:#"title"])
{
currentTweet.content = currentNodeContent;
NSLog(#"%#",currentNodeContent);
}
if ([elementname isEqualToString:#"link"])
{
currentFeed.WVUrl = currentNodeContent;
NSLog(#"%#",currentNodeContent);
}
}
if ([elementname isEqualToString:#"item"])
{
[self.feeds addObject:currentFeed];
currentFeed = nil;
[currentNodeContent release];
currentNodeContent = nil;
}
}
The problem in the Xml file is use of "&" Character.
Do one this just get the xml data in one string and then replace "&" with any unique string and then parse your xml.
While showing or use of xml data just check if the string you are getting contains the same unique string in it then replace that string with the "&".

iphone: NSMutable array is empty when using addObject in Xcode 4.3.2

I am parsing data using NSXMLParser.
I am able to get the parsed data. But when I add it to the NSMutableArray using addObject, the array is empty.
I am using the latest Xcode version.
Can someone please help me out.
The array I am working on is identificationTypes1
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
if ([elementName isEqualToString:#"Books"]) {
}
if ([elementName isEqualToString:#"Book"]) {
if ([elementName isEqualToString:#"title"]) {
self.identificationTypes1 =[[NSMutableArray alloc]init];
}
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if (!currentElementValue) {
currentElementValue =[[NSMutableString alloc]initWithString:string];
}
else {
[currentElementValue appendString:string];
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"Books"]) {
NSLog(#"Count is %#",[identificationTypes1 count]);
return;
}
if ([elementName isEqualToString:#"Book"]) {
}
if ([elementName isEqualToString:#"title"]) {
NSLog(#"Curre value is %#",currentElementValue);
[self.identificationTypes1 addObject:currentElementValue];
}
currentElementValue = nil;
}
NSMutabeArray *myArray = [[NSMUtableArray alloc]init];
[myArray addObject:<XML Data>];
You cannot nest elements as you have in didStartElement. Parsers do not allow that.
Take out the title out on its own and retest. You need to make new variables that are accessed conditionally.

get attribute values from returned XML

This is the xml I am getting from web:
<?xml version="1.0"?>
<abc>87C4A556-B7E5-5AE4-81FE-86BE0C6306E1</abc>
<abc2>P29077758</abc2>
<abc3>55AGD99D</abc3>
<abc4>147</abc4>
<abc5>1286259226</abc5>
<abc6>USA</abc6>
<abc7>US</abc7>
and using this to get attribute:
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if( [elementName isEqualToString:#"a"])
{
recordResults = FALSE;
// greeting.text = soapResults;
[soapResults release];
soapResults = nil;
}
}
Something like that, but I don't have any idea how can I get attribute from returned xml and assign those returned variables into my created variable. How can I do this?
http://blancer.com/tutorials/i-phone/76999/parsing-xml-files/ hope this helps !!!
I highly recommend using TouchXML to do your XML parsing.
I personally had all kinds of issues with NSXMLParser and ended up using TouchXML. Works a treat!
You should implement the following methods:-
One way you can use is :-
(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict
{
//check that the element is the one you want. If it is then initialize the string in which you want to store the value.
if(elementName isEqualToString:#"abc")
{
tempString = [[NSMutableString alloc] init];
}
}
(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
[tempString appendString:string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
if(elementName isEqualToString:#"abc")
{
self.StringToStore = tempString;
}
}

Extract channel title from RSS feed using NSXMLParser

how can I extract the title of a RSS channel while not getting in conflict with the title element of a news item?
If an element was found:
- (void)parser:(NSXMLParser *) parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
...
if ([elementName isEqualToString:#"channel") {
[currentChannel release];
currentChannel = nil;
currentChannel = [[NSMutableString alloc] init];
}
if ([elementName isEqualToString:#"item"]) {
...
}
}
If the end-tag was found:
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:#"channel") {
[channel setObject:currentChannelTitle forKey:#"title"];
}
if ([elementName isEqualToString:#"item"]) {
...
}
Do the parsing stuff:
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if ([currentElement isEqualToString:#"title") {
[currentChannelTitle appendString:string forKey:#"title"];
}
if ([currentElement isEqualToString:#"title"]) {
[currentTitle appendString:string];
}
...
}
And in the last part I have the problem. I have two "title" attributes. One for the "channel" element and one for the child element of it ("item"). But I need a distinction somehow. But how?
i think you want to get item title, in that case in viewDidload method take one bool type variable say flag in
viewDidload() method set flag=NO;
when during parsing you find a start element as "Item" set flag = YES, and In parser didendElement method when you found element as "Title", check that flag=YES or not. store only if it is YES.
and also in ParserDidEndElement when you find element as "Item" again set flag=NO;
I found another example to support different categories of the feed and I come up with the following solution:
First declare the variable in the *.h file.
#interface XMLParser : NSObject <NSXMLParserDelegate>{
...
NSMutableString * currentChannel;
}
In the *.m file synthesize and release the variable. In didStartElement ask which element you are currently working on. If it is a channel element, extract the title and store it in the above declared variable.
#implementation XMLParser
...
#synthesize currentChannel;
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
...
if ([elementName isEqualToString:#"item"]) {
...
}
// title is an attribute of the element channel
if ([currentElement isEqualToString:#"channel"]) {
[currentChannel appendString:[attributeDict objectForKey:#"title"]];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"item"]) {
...
if ([currentChannel isEqualToString:#"Your Channel Name"]) {
if ([currentCategory isEqualToString:#"Your category name"]) {
[items addObject:[item copy]];
}
} else {
[items addObject:[item copy]];
}
}
}
In didEndElement ask if the item belongs to a specific channel, and if then add it only if it is the defined category. So you can add/show only rss feeds, if they belong to a certain category.
So i've not tested it, because the channel only have one category. So I don't have to ask for the channel titel, to show only defined categories from a specific channel. But I think that should work.

How to parse the second child node from xml page in iphone

I am new to iphone development.I want parse an you-tube XML page and retrieve its contents and display in a RSS feed.
my xml page is
<entry>
<id>xxxxx</id>
<title>xxx xxxx xxxx</title>
<content>xxxxxxxxxxx</content>
<media:group>
<media:thumbnail url="http://tiger.jpg"/>
</media:group>
</entry>
To retrieve the content i am using xml parsing.
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
currentElement = [elementName copy];
if ([elementName isEqualToString:#"entry"]) {
entry = [[NSMutableDictionary alloc] init];
currentTitle = [[NSMutableString alloc] init];
currentcontent = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if ([elementName isEqualToString:#"entry"]) {
[entry setObject:currentTitle forKey:#"title"];
[entry setObject:currentDate forKey:#"content"];
[stories addObject:[entry copy]];
}}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
if ([currentElement isEqualToString:#"title"]) {
[currentTitle appendString:string];
} else if ([currentElement isEqualToString:#"content"]) {
[currentLink appendString:string];
}
}
I am able to retrieve id , title and content value and display it in a table-view.How can i retrieve tiger image URL and display it in table-view.Please help me out.Thanks.
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
currentElement = [elementName copy];
if ([elementName isEqualToString:#"media:thumbnail"])
imageUrl=[attributeDict objectForKey:#"url"];
}
Since you already have an if statement in this method, use else if for this one