How to parse multilevel xml in xcode - ios

can you help me with this program i'm trying to parse an xml file with two levels (i don't know the term so i call that way) here's the sample of my xml file
<?xml version="1.0" encoding="UTF-8"?>
<countries>
<country>
<countryname>Philippines</countryname>
<subsidiaries>
<subsidiary>
<name>Sart Philippines Inc.</name>
<address>Unit 10-A The World Empire Building, 330 Senator Gil Puyat Avenue Philippines, Philippines</address>
<phone>+63.2.929</phone>
<fax>+63.932</fax>
<email>enquiry.philippines#sarts.com</email>
<website>http://www.sartorius-mechatronics.com.ph</website>
</subsidiary>
</subsidiaries>
</country>
<country>
<countryname>Denmark</countryname>
<subsidiaries>
<subsidiary>
<name>Stedim Nordic A|S</name>
<address>Hoerskaetten 6d 2630 Taastrup, Denmark</address>
<phone>+45.7023.4400</phone>
<fax>+45.4630.4030</fax>
<email>ne.customersupport#sartorius.com</email>
<website></website>
</subsidiary>
<subsidiary>
<name>Nordic A|S</name>
<address>Hoerskaetten 6D 2630 Taastrup, Denmark</address>
<phone>+45.7523.8700</phone>
<fax>+45.4130.4020</fax>
<email>ne.customersupport#sartorius.com</email>
<website></website>
</subsidiary>
</subsidiaries>
</country>
</countries>
What i was planning to do was you choose a country, then you choose a subsidiary to view it's info. I was able to parse it but i was not able to show the Stedim Nordic A|S subsidiary.
here is my parser class
#implementation Parser
-(id)initParser
{
if (self == [super init])
{
app = (AppDelegate *) [[UIApplication sharedApplication]delegate];
}
return self;
}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI: (NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:#"countries"])
{
app.listArray = [[NSMutableArray alloc]init];
}
if ([elementName isEqualToString:#"country"])
{
theList = [[List 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:#"country"])
{
[app.listArray addObject:theList];
}
else {
if ([elementName isEqualToString:#"countryname"]) {
theList.countryname = currentElementValue;
}
if ([elementName isEqualToString:#"name"])
{
theList.name = currentElementValue;
}
if ([elementName isEqualToString:#"address"])
{
theList.address = currentElementValue;
}
if ([elementName isEqualToString:#"phone"])
{
theList.phone = currentElementValue;
}
if ([elementName isEqualToString:#"fax"])
{
theList.fax = currentElementValue;
}
if ([elementName isEqualToString:#"email"])
{
theList.email = currentElementValue;
}
if ([elementName isEqualToString:#"website"])
{
theList.website = currentElementValue;
}
currentElementValue = nil;
}
}
#end
I can't explain it well but i hope you can help me , if you can send me a link for a tutorial for this kind of issues i would really appreciate it

The issue is because on your second country element there is two subsidiary.
So you need to modify your code like:
You need another NSString for holding the Country Name. Because there is a single Country name element for your two subsidiary.
NSString *temp = nil;
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI: (NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqualToString:#"countries"])
{
app.listArray = [[NSMutableArray alloc]init];
}
if ([elementName isEqualToString:#"subsidiary"])
{
theList = [[List alloc]init];
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI: (NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"subsidiary"])
{
theList.countryname = temp;
[app.listArray addObject:theList];
}
else
{
if ([elementName isEqualToString:#"countryname"])
{
temp = currentElementValue;
}
if ([elementName isEqualToString:#"name"])
{
theList.name = currentElementValue;
}
if ([elementName isEqualToString:#"address"])
{
theList.address = currentElementValue;
}
if ([elementName isEqualToString:#"phone"])
{
theList.phone = currentElementValue;
}
if ([elementName isEqualToString:#"fax"])
{
theList.fax = currentElementValue;
}
if ([elementName isEqualToString:#"email"])
{
theList.email = currentElementValue;
}
if ([elementName isEqualToString:#"website"])
{
theList.website = currentElementValue;
}
currentElementValue = nil;
}
}

Well you can call the parser recursively. If you know what you are looking for search if it is available and take its value if present. i would suggest you to look into gdata xml parser

Related

Objective-C - how can separately parse attributes of my XML?

I'm working on an application where I use XML parsing in UITableView. I can not figure out how I'm separately parses attributes rok1 and rok2. If I use [_element isEqualToString: # "jmeno"] application works well, but it displayed to me in UITableView together rok1 and rok2 and do not want it. Thx for your help.
There is my parser code:
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {
self.element = elementName;
if ([_element isEqualToString:#"rok1"])
{
_item = [[NSMutableDictionary alloc] init];
self.nazev = [[NSMutableString alloc] init];
self.definice = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if ([self.element isEqualToString:#"nazev"])
{
[self.nazev appendString:string];
}
else if ([self.element isEqualToString:#"def"])
{
[self.definice appendString:string];
}
}
- (void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:#"rok1"])
{
Slova *thisSvatek = [[Slova alloc] initWithName:self.nazev
definice:self.definice];
[self.svatkyArray addObject:thisSvatek];
}
self.element = nil;
}
And example of my XML:
<?xml version="1.0" encoding="UTF-8" ?>
<menu>
<rok1>
<jmeno>
<nazev>Prvni</nazev>
<def>blblbla</def>
<jmeno>
<nazev>Druhy</nazev>
<def>blbablabal</def>
</jmeno>
</rok1>
<rok2>
<jmeno>
<nazev>Prvni</nazev>
<def>blblbla</def>
</jmeno>
</rok2>
</menu>
You need to keep track of your "state" as you are parsing the XML document. One simple approach is simply to add a boolean property that indicates that you are processing 'inside' the target element.
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {
self.element = elementName;
if ([elementName isEqualToString:#"rok1"])
{
self.foundTarget=YES;
self.nazev = [[NSMutableString alloc] init];
self.definice = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (self.foundTarget) {
if ([self.element isEqualToString:#"nazev"])
{
[self.nazev appendString:string];
}
else if ([self.element isEqualToString:#"def"])
{
[self.definice appendString:string];
}
}
}
- (void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:#"rok1"])
{
Slova *thisSvatek = [[Slova alloc] initWithName:self.nazev
definice:self.definice];
[self.svatkyArray addObject:thisSvatek];
self.foundTarget=NO;
}
self.element = nil;
}
A more sophisticated approach is to build some sort of data structure, such as a dictionary, that represents your XML
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {
self.element = elementName;
if ([elementName isEqualToString:#"rok1"] || [elementName.isEqualToString:#"rok2"])
{
self.nazev = [[NSMutableString alloc] init];
self.definice = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if ([self.element isEqualToString:#"nazev"])
{
[self.nazev appendString:string];
}
else if ([self.element isEqualToString:#"def"])
{
[self.definice appendString:string];
}
}
- (void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:#"rok1"] || [elementName.isEqualToString:#"rok2"])
Slova *thisSvatek = [[Slova alloc] initWithName:self.nazev
definice:self.definice];
self.rokDictionary[elementName]=thisSvatek; // self.rokDictionary is an NSMutableDictionary
}
self.element = nil;
}
To separate out the various 'jmeno' tags, you need to handle them in didStartElement & didEndElement -
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {
self.element = elementName;
if ([elementName isEqualToString:#"rok1"] || [elementName.isEqualToString:#"rok2"])
{
self.jmenoArray=[NSMutableArray new];
}
else if ([elementName isEqualToString:#"jmeno"]) {
self.nazev = [[NSMutableString alloc] init];
self.definice = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if ([self.element isEqualToString:#"nazev"])
{
[self.nazev appendString:string];
}
else if ([self.element isEqualToString:#"def"])
{
[self.definice appendString:string];
}
}
- (void)parser:(NSXMLParser *)parser
didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:#"jmeno"]) {
Slova *thisSvatek = [[Slova alloc] initWithName:self.nazev
definice:self.definice];
[self.jemnoArray addObject:thisSvatek];
}
else if ([elementName isEqualToString:#"rok1"] || [elementName.isEqualToString:#"rok2"])
self.rokDictionary[elementName]=self.jmenoArray; // self.rokDictionary is an NSMutableDictionary
self.jmenoArray=nil;
}
self.element = nil;
}

Count xml multiple child tag in ios

My XML is looks like this :
<a>
<b>b1</b>
<c>c1</c>
<d>
<x>apple1</x>
<y>orange1</y>
<z>Mango1</z>
</d>
<d>
<x>apple2</x>
<y>orange2</y>
<z>Mango2</z>
</d>
<d>
<x>apple3</x>
<y>orange3</y>
<z>Mango3</z>
</d>
</a>
<a>
<b>b2</b>
<c>c2</c>
<d>
<x>apple4</x>
<y>orange4</y>
<z>Mango4</z>
</d>
<d>
<x>apple5</x>
<y>orange5</y>
<z>Mango5</z>
</d>
</a>
Here i want to count the number of <d>...</d> tag in each <a>...</a> in objectiveC. The answer will be 3 for first <a> tag and 2 for second <a> tag. Please give me a suggestion. Thanks.
Here is my code :
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementname isEqualToString:#"a"])
{
currentBook = [[BookListInfo alloc] init];
currentNodeContentBook=[[NSMutableString alloc] init];
isInChapterDTO = false;
}
else if ([elementname isEqualToString:#"d"])
{
//currentBook = [[BookListInfo alloc] init];
currentNodeContentChapters=[[NSMutableString alloc] init];
isInChapterDTO = true;
currentChapter = [[Chapters alloc] init];
}
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if(isInChapterDTO==TRUE)
{
if ([elementname isEqualToString:#"x"])
{
currentChapter.chapterId = currentNodeContentChapters;
}
if ([elementname isEqualToString:#"y"])
{
NSString*appendString=#"B";
currentNodeContentChapters=[appendString stringByAppendingString:currentNodeContentChapters];
currentChapter.chapterName = currentNodeContentChapters;
}
if ([elementname isEqualToString:#"z"])
{
currentChapter.chapterDurationAsSec = currentNodeContentChapters;
}
}
else
{
if ([elementname isEqualToString:#"b"])
{
[currentNodeContentBook stringByAppendingString:currentNodeContentBook];
currentBook.bookId = currentNodeContentBook;
}
if ([elementname isEqualToString:#"c"])
{
......................
}
}
}
if ([elementname isEqualToString:#"a"])
{
[bookListArray addObject:currentBook];
currentBook = nil;
currentNodeContentBook = nil;
}
else if ([elementname isEqualToString:#"d"])
{
[chapterListArray addObject:currentChapter];
//currentBook.ChapterList.Add(currentChapter);
currentChapter = nil;
isInChapterDTO = false;
}
Try this:
int dCount;
BOOL isATag;
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementname isEqualToString:#"a"])
{
isATag = YES;
}
else if ([elementname isEqualToString:#"d"])
{
if(isATag){
dCount++;
}
}
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementname isEqualToString:#"a"]){
NSLog(#"d tag count between A: %d",dCount);
dCount=0;
isATag = NO;
}
}
Declare the below objects
int count;
BOOL insideATag;
NSMutableArray *dCounts;
Initialize the dCounts in viewDidLoad
dCounts = [[NSMutableArray alloc]init];
Add the below delegate methods
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementname isEqualToString:#"a"])
{
insideATag = YES;
count = 0;
}
}
- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementname namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([element isEqualToString:#"a"]){
insideATag = NO;
[dCounts addObject:count]
} else if ([elementname isEqualToString:#"d"] && insideATag)
{
count++;
}
}
If you want count of 'd' tags inside first 'a' tag, then
NSLog(#"Count of d : %i",[dCounts objectAtIndex:0]);

How can I set key-value pair in NSMutableDictionary as XML attribute-element values using NSXMLParser

I am using NSXMLParser to parse my XML with the following structure:
<characters>
<character>
<literal>本</literal>
<codepoint>
<cp_value cp_type="ucs">672c</cp_value>
<cp_value cp_type="jis208">43-60</cp_value>
</codepoint>
</character>
</characters>
I want to use the cp_value element's attribute_value as a key and the element value (e.g. 672c) as the value and place this key-value pair in my NSMutableDictionary *_codepoint. After parsing, I want the result (in the console) to look like this:
_codepoint: {
"ucs"=672c;
"jis208"=43-60;
}
As I have implemented the parser (code follows), I am getting this back in the console:
2013-01-22 22:12:46.199 MyApp[13391:c07] _codepoint: {
ucs = "\n \n ";
}
2013-01-22 22:12:46.201 MyApp[13391:c07] _codepoint: {
jis208 = "\n \n 672c\n ";
}
First - the values and keys are out-of-sync and second, the value for the jis208 element is not getting read-in. Second, I'm not sure what these \n and whitespaces are. Can anybody please give some advice?
The code I have written is:
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict
{
if([elementName isEqualToString:#"characters"]) {
appDelegate.characters = [[NSMutableArray alloc] init];
} else if ([elementName isEqualToString:#"character"]) {
aCharacter = [[Character alloc] init];
} else if ([elementName isEqualToString:#"cp_value"]) {
if (!_codepoint) _codepoint = [[NSMutableDictionary alloc] init];
[_codepoint setValue:currentElementValue forKey:[attributeDict valueForKey:[[attributeDict allKeys] lastObject]]];
NSLog(#"_codepoint: %#", _codepoint);
}
- (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:#"characters"]
// cp_values will be copied from a local NSMutableDictionary *_codepoint
|| [elementName isEqualToString:#"codepoint"]
) return;
if ([elementName isEqualToString:#"character"]) {
[appDelegate.characters addObject:aCharacter];
[aCharacter release];
} else if ([elementName isEqualToString:#"cp_value"]){
[aCharacter.codepoint addObject:_codepoint];
}
}
Thank you very much for looking.
problem is that you are adding currentElementValue to _codepoint before reading actual value into currentElementValue i.e you are adding it in when cp_value is started. you should add currentElementValue to _codepoint in didEndElement: delegate method.Then you'll get expected result.Modify your code like this:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if([elementName isEqualToString:#"characters"]) {
appDelegate.characters = [[NSMutableArray alloc] init];
} else if ([elementName isEqualToString:#"character"]) {
aCharacter = [[Character alloc] init];
} else if ([elementName isEqualToString:#"cp_value"]) {
if (!_codepoint) _codepoint = [[NSMutableDictionary alloc] init];
currentAttributeKey = [[NSMutableString alloc]initWithString:[attributeDict valueForKey:[[attributeDict allKeys] lastObject]]];
}
- (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:#"characters"] || [elementName isEqualToString:#"codepoint"])
return;
if ([elementName isEqualToString:#"character"]) {
[appDelegate.characters addObject:aCharacter];
[aCharacter release];
} else if ([elementName isEqualToString:#"cp_value"]){
[_codepoint setValue:[[currentElementValue componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] componentsJoinedByString:#""] forKey:currentAttributeKey];
currentElementValue = [[NSMutableString alloc]init];
NSLog(#"_codepoint: %#", _codepoint);
[aCharacter.codepoint addObject:_codepoint];
}
}
where currentAttributeKey is NSMutableString that will store the attributes.In your case ucs and jis208

Array in Array NSXML Parser IOS

<events>
<status>OK</status>
<name>20121203</name>
<descripcion></descripcion>
<url_IOS></url_IOS>
<printers>
<coordenadas_LAT>40.44702054203392</coordenadas_LAT>
<coordenadas_LON>-3.703991174697876</coordenadas_LON>
</printers>
<printers>
<coordenadas_LAT>40.448416693004596</coordenadas_LAT>
<coordenadas_LON>-3.7036800384521484</coordenadas_LON>
</printers>
</events>
====
Hi All ,
I have this XML and Im parsing like that:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
// the start of a 'booth' element is been encountered
if([elementName isEqualToString:#"events"])
{
self.tmpEvent = [[PublicPrivateEvent alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
currentElementValue = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"coordenadas_LAT"]) {
tmpEvent.latitude =currentElementValue;
}
if([elementName isEqualToString:#"coordenadas_LON"])
{
tmpEvent.longtitude = currentElementValue ;
}
if([elementName isEqualToString:#"description"])
{
tmpEvent.description = currentElementValue;
}
if([elementName isEqualToString:#"url_IOS"])
{
tmpEvent.imgurlios6 = currentElementValue;
}
if([elementName isEqualToString:#"printers"])
{
[printers addObject:tmpEvent];
currentElementValue = nil;
}
if([elementName isEqualToString:#"status"])
{
[events addObject:tmpEvent];
currentElementValue = nil;
}
}
===
I have 2 printers , but when im trying to get this 2 coordinates, but im getting only the last coordinate twice? What is the problem. Where am i wrong Could you help me?
Thanks in advance..
Yes. I was. Here below is my solution. Hope helps.
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
// the start of a 'booth' element is been encountered
if([elementName isEqualToString:#"evento"])
{
self.tmpEvent = [[PublicPrivateEvent alloc] init];
self.dictionaryPrinters = [[NSMutableDictionary alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
currentElementValue = (NSMutableString *) [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"coordenadas_LAT"]) {
[self.dictionaryPrinters setValue:currentElementValue forKey:#"coordenadas_LAT"];
tmpEvent.latitude =currentElementValue;
}
if([elementName isEqualToString:#"coordenadas_LON"])
{
[self.dictionaryPrinters setValue:currentElementValue forKey:#"coordenadas_LON"];
tmpEvent.longtitude = currentElementValue ;
}
if([elementName isEqualToString:#"description"])
{
tmpEvent.description = currentElementValue;
}
if([elementName isEqualToString:#"url_imagen_evento_LDPI"])
{
tmpEvent.imgurlldp = currentElementValue;
}
if([elementName isEqualToString:#"nombre"])
{
tmpEvent.name = currentElementValue;
}
if([elementName isEqualToString:#"url_imagen_evento_MDPI"])
{
tmpEvent.imgurlmdp = currentElementValue;
}
if([elementName isEqualToString:#"url_imagen_evento_HDPI"])
{
tmpEvent.imgurlhdp = currentElementValue;
}
if([elementName isEqualToString:#"url_imagen_evento_XHDPI"])
{
tmpEvent.imgurlxhdp = currentElementValue;
}
if([elementName isEqualToString:#"url_imagen_evento_IOS5"])
{
tmpEvent.imgurlios5 = currentElementValue;
}
if([elementName isEqualToString:#"url_imagen_evento_IOS6"])
{
tmpEvent.imgurlios6 = currentElementValue;
}
if([elementName isEqualToString:#"impresora"])
{
[printers addObject:[self.dictionaryPrinters copy]];
}
if([elementName isEqualToString:#"status"])
{
[events addObject:tmpEvent];
currentElementValue = nil;
}

How to parse data from a website using NSXMLParser

I want to get the updates from a website based on the titles and links which is in xml format.
I have tried with the code below but it's not working. In console it is showing the message:
2011-11-03 14:45:05.987 tabbar[673:e903] * Terminating app due to
uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFString
isEqualtostring:]: unrecognized selector sent to instance 0x5746830'
If I run again, the table view is loading but there is no data in the table cells.
It is showing this message at the line if ([elementName isEqualtostring:#"item"]):
program received signal SIGABRT
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
classelement = elementName;
if ([elementName isEqualtostring:#"item"])
{
itemselected = YES;
multitle = [[NSMutableString alloc]init];
mullink = [[NSMutableString alloc]init];
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedname:(NSString *)qName
{
if ([elementName isEqualToString:#"item"])
{
itemselected = NO;
[titlearray addObject:multitle];
[linkarray addObject:mullink];
[multitle release];
[mullink release];
[self.tbl reloadData];
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (itemselected)
{
if ([classelement isEqualToString:#"title"])
{
NSLog(#"%#",string);
[multitle appendString:multitle];
}
else if([classelement isEqualToString:#"link"])
{
[multitle appendString:string];
}
}
}
If you are reading directly from a website more than likely you are getting "invalid" characters. As soon as the parser see's these invalid characters it will crash. I would suggest looking at using "HPPLE Parser". It works much better and wont crash if invalid characters come in.
Hpple information here: http://blog.objectgraph.com/index.php/2010/02/24/parsing-html-iphone-development/
Finally I got it. What I did is I have taken two NSMutableArrays and two NSMutableStrings and I appended the items to the strings, and later those strings I appended to the two arrays.
(void)viewDidLoad
{
titlearray = [[NSMutableArray alloc]init];
linkarray = [[NSMutableArray alloc]init];
NSString *rssaddress =#"http://www.greenday.com/rss";
NSURL *url = [NSURL URLWithString:rssaddress];
xmlparser = [[NSXMLParser alloc]initWithContentsOfURL:url];
[xmlparser setDelegate:self];
[xmlparser parse];
[super viewDidLoad];
}
(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
classelement = elementName;
if([elementName isEqualToString:#"item" ])
{
itemselected = YES;
titlestrng = [[NSMutableString alloc]init];
linkstrng = [[NSMutableString alloc]init];
}
}
(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([elementName isEqualToString:#"item" ])
{
itemselected = NO;
[titlearray addObject:titlestrng];
[linkarray addObject:linkstrng];
[titlestrng release];
[linkstrng release];
[self.tb reloadData];
}
}
(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if(itemselected)
{
if([classelement isEqualToString:#"title"])
{
[titlestrng appendString: string];
NSLog(#"%#",titlestrng);
}
else if ([classelement isEqualToString:#"link"])
{
[linkstrng appendString:string];
NSLog(#"%#",linkstrng);
}
}
}

Resources