I am using NSXMLParser to parse this XML: http://itunes.apple.com/gb/rss/topsongs/limit=50/explicit=true/xml. I am trying to parse an element called "im:image". My problem is that there are three elements with the name "im:image". How can I only parse the data from the second "im:image", or how can I add each single one to an array?
This is probably not the best way to do it, but when something like this happened to me I simply created a NSInteger named counter. Then in didStartElement I did this: (I was looking for the second element in my case)
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {
if([elementName isEqualToString:#"yweather:forecast"])
{
int code = [[attributeDict objectForKey:#"code"] intValue];
if (counter == 0) {
}
if (counter == 1) {
conditionCode = code;
}
counter ++;
}
}
In the didStartElement method of your custom delegate, check attributes and ensure that it has height set to 60 (each of the 'same' XML elements has a different height attribute). The attributes is an NSDictionary with keys for name of the attributes and values for values of the attributes. Here is an example of roughly how you would do it:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
if ([[attributeDict objectForKey:#"height"] isEqualToString:#"60"]) {
NSLog(#"store");
}
}
Related
I want to set string "EMPTY"for empty tag XML in NSXMLParse. Exm: my xml:
<STATE>0</STATE>
<MEMO/>
In above XML, MEMO tag is empty. I want to when NSXMLParse parse into tag, if it is empty,get string "EMPTY" in label. I used bellow code to parse xml:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
NSLog(#"Did start element");
if ( [elementName isEqualToString:#"FILENAME"])
{
XML_FIELD = FILENAME_CLOUD2;
NSLog(#"found rootElement");
return;
}
else if ( [elementName isEqualToString:#"MEMO"])
{
NSLog(#"found rootElement");
XML_FIELD = MEMO;
return;
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
NSLog(#"Did end element");
if ([elementName isEqualToString:#"FILENAME"])
{
NSLog(#"rootelement end");
}
[strMemoEmpty setString:#"EMPTY"];
XML_FIELD = UNIMPORTANT2;
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
//NSString *tagName = #"USER_NAME";
if (XML_FIELD == FILENAME_CLOUD2)
{
NSLog(#"Value %#",string);
[FileCompletedArray insertObject:string atIndex:0];
}
else if (XML_FIELD == MEMO)
{
NSLog(#"Value %#",string);
if (string != nil) {
[strMemoEmpty setString:#""];
[strMemoEmpty appendString: string];
NSLog(#"foundResults: %#",strMemoEmpty);
}
[MemoArray insertObject:string atIndex:0];
}
}
I used above code but it not check MEMO tag is empty. It missed when parse. Do you have any suggestions? Thanks in advance
The construction of your code is a bit strange and messy, you should reorganise so:
didStartElement creates new storage for the starting element and sets any flags
foundCharacters doesn't have logic, it just appends the received string to a mutable buffer (it could be called multiple times for the same tag)
didEndElement contains the logic (and checks the length of the found characters and substitutes your empty value if required)
The way you have it now means that partial data may be saved in foundCharacters and, because that method isn't called for empty tags, some of your logic is being set but never actually saved.
iam developing one application.In that iam using the xml parsing.That xml file contain the 4 category tags and other tags.From the xml file i want to get the data of category tag.At the time of getting the category data,every time i print the array of category values.That show correctly.But after completion of parsing, another tag data will be append to last category name.My parsing code is like below.
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if(self.presentvalue)
{
[presentvalue appendString:string];
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if(![elementName compare:#"category"])
{
[categories addObject:presentvalue];
NSLog(#"%#",presentvalue);
NSLog(#"Number of elements %#",categories);
}
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if([elementName isEqualToString:#"category"])
{
presentvalue=[NSMutableString string];
}
}
And my xml file content is like
<lesson>
<categories>
<category id="1">1</category>
<category id="2">2</category>
<category id="3">3</category>
</categories>
<references>
<reference id="1" type="youtube" categoryid="2" name="Boyles law">
<url><![CDATA[http://www.youtube.com/watch?v=J_I8Y-i4Axc]]>
</url>
</reference>
</references>
</lesson>
From this xml i got the array values like 1,2,3http://www.youtube.com/watch?v=J_I8Y-i4Axc.Like this i got the result.So please tell me how to get the category values without that extra data.
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:#"category"]) {
NSLog(#"Node is found correctly");
if(presentvalue == nil)
presentvalue = [NSMutableString string];
else
[presentvalue setString:#""];
}
else {
presentvalue = nil;
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
[presentvalue appendString:string];
if (presentvalue)
{
[self.tempArray addObject:presentvalue]; // add this line. create a tempArray containing all the strings.
presentvalue = nil;
}
}
this should help u in your parsing. hope it helps. happy coding :)
place check in your xml parsing code. that if the starting/ending element name is category. add objects to array else do nothing. just passout
I think this line look strange
if(![elementName compare:#"category"])
Shouldn't it be like this? (without !)
if([elementName compare:#"category"])
edited
Try replacing this to the didEndElement
if([elementName isEqualToString:#"category"])
{
[categories addObject:presentvalue];
presentValue = [NSMutableString string];
NSLog(#"%#",presentvalue);
NSLog(#"Number of elements %#",categories);
}
How can I such type of Response of XML, using NSXMLParser, I am confused about two "clicks", it will hit, so how to manage flow and save data with one object, help me out,
</campaign_summary_response>
<summary> <clicks>6</clicks>
<conversions>1</conversions>
<conversion_rate>0.1666666666666666666666666667</conversion_rate>
<revenue>22.26555000000000</revenue>
<revenue_converted>22.26555000000000</revenue_converted>
<currency_symbol>$</currency_symbol>
<currency_symbol_converted>$</currency_symbol_converted>
</summary>
<campaigns>
<campaign> <offer_id>100</offer_id>
<offer_name>$100 Wendy's Gift Card + Free Frosty</offer_name>
<campaign_id>1781</campaign_id> <vertical_name>Free Stuff</vertical_name>
<price_format>CPA</price_format>
<price>0.0000</price>
<impressions>0</impressions>
<clicks>6</clicks>
<conversions>1</conversions>
<conversion_rate>0.1666666666666666666</conversion_rate>
<revenue>15.0000</revenue>
<revenue_converted>22.26555000000000</revenue_converted>
<epc>2.50000000000000000000000</epc>
<currency_symbol>€</currency_symbol>
<currency_symbol_converted>$</currency_symbol_converted>
</campaign> </campaigns>
</campaign_summary_response>
How do I code following delegate method
- (void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName {
So that i can save all values in one object and show on display.
In didStartElement method.
if([elementName isEqualToString:#"summary"]) summary = YES;
if([elementName isEqualToString:#"campaign"]) campaign = YES;
In didEndElement method.
if(summary) {
if([elementName isEqualToString:#"revenue"]) // revenue in summary
if([elementName isEqualToString:#"summary"]) summary = NO;
}
if(campaign) {
if([elementName isEqualToString:#"revenue"]) // revenue in campaign
if([elementName isEqualToString:#"campaign"]) campaign = NO;
}
I'm newbie on iPhone development.I want to parse XML file like this to get attribute value.
<Root>
<element att_1 ="value1" att_2 ="value2" />
<element att_1 ="value1" att_2 ="value2" />
.
.
.
<Root/>
Normally XML file
<element att="..."> content <element/>
I use this at didEndElement
if([elementName isEqualToString:#"element"]){
// Do something
}
How to check empty tag ? Advice me Please.
Thank you.
sorry for my bad english.
=====================================================================
Now I have new problem.when I run the application(simulator) it stuck and show message"Thread1:Stopped at breakpoint" in didStartElement.I guess I do something wrong.
StudyList.xml
<StudyList>
<study description="20040311181130" modsInStudy="" pat_birth="19760822" pat_id="47-3450" pat_name="Ekachai Chaichanasiri" refPhy="" study_date="Sun Jan 11 00:03:00 ICT 2004" study_id="696122224" study_iuid="1.2.392.200036.9123.100.200.20040311181130"/>
<study description="XoranCAT Study" modsInStudy="" pat_birth="19821117" pat_id="63" pat_name="Wantana Areeprayolkij" refPhy="" study_date="Fri Jan 28 00:04:00 ICT 2005" study_id="" study_iuid="1.2.826.0.1.3680043.2.594.4041.16900.9840.32723.30648"/>
</StudyList>
Delegate
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
if ([elementName isEqualToString:#"StudyList"]) {
//Initialize the array.
appDelegate.studyList = [[NSMutableArray alloc] init];
} else if ([elementName isEqualToString:#"study"]) {
//Initialize the study.
aStudy.patientBrith = [attributeDict objectForKey:#"pat_birth"] ;
aStudy.patientID = [attributeDict objectForKey:#"pat_id"];
aStudy.patientName = [attributeDict objectForKey:#"pat_name"];
aStudy.studyDate = [attributeDict objectForKey:#"study_date"];
NSLog(#"Patient name: %#",aStudy.patientName);
NSLog(#"Patient ID: %#",aStudy.patientID);
NSLog(#"Patient Birth: %#" ,aStudy.patientBrith);
NSLog(#"Study Date: %#" ,aStudy.studyDate);
}
NSLog(#"Process Element");
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
//Nothing to do because XML file dose not have text node
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
//End if XML file nothing to do.
if ([elementName isEqualToString:#"StudyList"]) {
return;
//Add study object in to array and release the object.
if ([elementName isEqualToString:#""]||elementName == nil) {
[appDelegate.studyList addObject:aStudy];
}
}
}
NSLog(#"Patient name: %#",aStudy.patientName);
NSLog(#"Patient ID: %#",aStudy.patientID);
NSLog(#"Patient Birth: %#" ,aStudy.patientBrith);
NSLog(#"Study Date: %#" ,aStudy.studyDate);
***Output of above is null.
What wrong,Please tell me in right way.
Retain the value of string in this function
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
In - (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
Check
if ([retainedString isEqualToString:#"" ] || [retainString == nil)
Then the value is empty.
i want to get data from xml parser ?
how can i get from xml parser ?
which methods for that and how can i get that ?
any example for that
http://codesofa.com/blog/archive/2008/07/23/make-nsxmlparser-your-friend.html
Have a look at this..
NSXMLParser calls your "delegate", which has to implement certain methods. When the parser calls your delegate, you grab the data at that time.
For my simple xml file, I just implement the main "Element" one, which only recognizes <place lat="number" lon="number"... , and starts like this...
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict
{
// we here recognize our one crucial element, "place", and its attributes.
if([elementName compare:#"place"] == 0)
{
OmWayPoint p = {0};
p.lat = [[attributeDict valueForKey:#"lat"] doubleValue];
p.lon = [[attributeDict valueForKey:#"lon"] doubleValue];
p.alt = [[attributeDict valueForKey:#"alt"] doubleValue];
int wpCount = [self addWayPoint:&p];
...
}