I am creating an IOS application. In which I have to use SOAP web-service to get some details. So that I have used SUDZ-C to generate the stub. I can able to call web-service and got the response. But I can't parse the response. The below is the XML response.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ViewAppTrackResponse xmlns="http://service.cmp.app.com">
<ViewAppTrackResponseReturn>
<ns1:monthBO xmlns:ns1="http://response.cmp.app.com">
<monthListItem>
<ns2:date xmlns:ns2="http://bean.cmp.app.com">1-2-2014, Saturday (nonworking day)</ns2:date>
<ns3:lockStatus xmlns:ns3="http://bean.cmp.app.com">N</ns3:lockStatus>
<ns4:dailyTime xsi:nil="true" xmlns:ns4="http://bean.cmp.app.com"/>
<ns5:taskListNew xsi:nil="true" xmlns:ns5="http://bean.cmp.app.com"/>
</monthListItem>
<monthListItem>
<ns6:date xmlns:ns6="http://bean.cmp.app.com">2-2-2014, Sunday (nonworking day)</ns6:date>
<ns7:lockStatus xmlns:ns7="http://bean.cmp.app.com">N</ns7:lockStatus>
<ns8:dailyTime xmlns:ns8="http://bean.cmp.app.com">04:00</ns8:dailyTime>
<ns9:taskListNew xmlns:ns9="http://bean.cmp.app.com">
<taskListItem>
<ns9:trackId>1070</ns9:trackId>
<ns9:taskId>14</ns9:taskId>
</taskListItem>
<taskListItem>
<ns9:trackId>1094</ns9:trackId>
<ns9:taskId>44</ns9:taskId>
</taskListItem>
</ns9:taskListNew>
</monthListItem>
<monthListItem>
<ns10:date xmlns:ns10="http://bean.cmp.app.com">3-2-2014, Monday</ns10:date>
<ns11:lockStatus xmlns:ns11="http://bean.cmp.app.com">N</ns11:lockStatus>
<ns12:dailyTime xmlns:ns12="http://bean.cmp.app.com">08:00</ns12:dailyTime>
<ns13:taskListNew xmlns:ns13="http://bean.cmp.app.com">
<taskListItem>
<ns13:trackId>1071</ns13:trackId>
<ns13:taskId>14</ns13:taskId>
</taskListItem>
<taskListItem>
<ns13:trackId>1073</ns13:trackId>
<ns13:taskId>44</ns13:taskId>
</taskListItem>
</ns13:taskListNew>
</monthListItem>
</ns1:monthBO>
<ns14:userId xsi:nil="true" xmlns:ns114="http://response.cmp.app.com"/>5</ns14:userId>
</ViewAppTrackResponseReturn>
</ViewAppTrackResponse>
</soapenv:Body>
</soapenv:Envelope>
Can anyone help me to parse this response. This will helpful for me.
LibXML2 is included in Cocoa.
http://www.raywenderlich.com/553/xml-tutorial-for-ios-how-to-choose-the-best-xml-parser-for-your-iphone-project
http://www.cocoawithlove.com/2008/10/using-libxml2-for-parsing-and-xpath.html
You can use NSXMLParser class to parse this.Using its delegate methods you can parse. I am posting my try to parse your xml.It is not completed.I am giving you a basic code for parsing. You have to do the remaining.
Here "xmlInput" is of type NSString with your xmlstring.
NSData* xmlData = [xmlInput dataUsingEncoding:NSUTF8StringEncoding];
NSXMLParser * xmlParser = [[NSXMLParser alloc] initWithData:[xmlData copy]];
[xmlParser setDelegate:(id)self];
[xmlParser setShouldResolveExternalEntities: YES];
[xmlParser parse];
Create an xmlparser object and input your xmlData.Set its delegates.
//this delegate calls when parsing start.Only once.
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
recordResults = NO;//declared in .h
MonthFlag = NO;//declared in .h
TaskFlag = NO;//declared in .h
Arry = nil;//declared in .h
}
// This delgate calls when each tag name is found.
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *)qName
attributes: (NSDictionary *)attributeDict
{
strElementName = [elementName copy];//strElementName is declared in .h
NSLog(#"%#",strElementName);
if([elementName isEqualToString:#"monthListItem"]){
MonthFlag = YES;
}
if([elementName isEqualToString:#"taskListItem"]){
TaskFlag = YES;
}
strElementValue = #""; //strElementValue is declared in .h
}
//This is called when each tag value is found.
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
strElementValue = [NSString stringWithFormat:#"%#%#", strElementValue,[string copy]];
NSLog(#"%#",strElementValue);
//NSLog(#"%# : %#",strElmentName,strElementValue);
recordResults=(strElementValue.length > 0);
}
// This deleagte will call in the end of each tag name.
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI: (NSString *)namespaceURI qualifiedName:(NSString *)qName
{
NSLog(#"%# - %#",elementName,strElementValue);
if (recordResults) {
if (MonthFlag) {
if(dicTemp==nil){
dicTemp = [[NSMutableDictionary alloc] init];
for (int i=0; i<10; i++) {
[dicTemp setObject:#"" forKey:strElementName];
}
}
[dicTemp setObject:strElementValue forKey:elementName ];
}
}
if(([elementName isEqualToString:#"monthListItem"] ) && dicTemp!=nil) {
if(Arry==nil)Arry = [[NSMutableArray alloc] init];
[Arry addObject:[dicTemp copy]];
dicTemp = nil;
[dicTemp release];
MonthFlag = NO;
NSLog(#"arry test %#",[Arry description]);
}
}
// This delegate will call when parsing finishes . only once
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
recordResults = NO;
}
Related
I'm trying to gather the data from an XML file and add to an array. The data looks something like this..
<Placemark>
<name><![CDATA[Kingsway (Start)]]></name>
<description><![CDATA[]]></description>
<TimeStamp><when>2014-04-30T17:03:28.681Z</when></TimeStamp>
<styleUrl>#start</styleUrl>
<Point>
<coordinates>-1.408894,52.13977,176.0</coordinates>
</Point>
</Placemark>
<Placemark id="tour">
<name><![CDATA[Kingsway]]></name>
<description><![CDATA[]]></description>
<styleUrl>#track</styleUrl>
<ExtendedData>
<Data name="type"><value><![CDATA[running]]></value></Data>
</ExtendedData>
<gx:MultiTrack>
<altitudeMode>absolute</altitudeMode>
<gx:interpolate>1</gx:interpolate>
<gx:Track>
<when>2014-04-30T17:03:28.681Z</when>
<gx:coord>-1.408894 52.13977 176.0</gx:coord>
<when>2014-04-30T17:03:31.071Z</when>
<gx:coord>-1.407839 52.139166 174.0</gx:coord>
<when>2014-04-30T17:03:32.070Z</when>
<gx:coord>-1.407486 52.138963 175.0</gx:coord>
<when>2014-04-30T17:03:33.073Z</when>
<gx:coord>-1.407142 52.138755 174.0</gx:coord>
<when>2014-04-30T17:03:34.073Z</when>
<gx:coord>-1.406805 52.138555 173.0</gx:coord>
<when>2014-04-30T17:03:35.073Z</when>
<gx:coord>-1.40663 52.138441 173.0</gx:coord>
<when>2014-04-30T17:03:36.601Z</when>
<gx:coord>-1.405929 52.138027 172.0</gx:coord>
<when>2014-04-30T17:03:37.601Z</when>
<gx:coord>-1.405574 52.137817 172.0</gx:coord>
I'm only interested in the values following the tag gx:coord, so I'm parsing the file using the code below.
- (void)loadMap:(NSInteger)selJourney
{
NSString *journey = #"KML_Sample";
NSString *path = [[NSBundle mainBundle] pathForResource:journey ofType:#"kml"];
[self parseXMLFile:path];
}
- (void)parseXMLFile:(NSString *)pathToFile
{
NSXMLParser *addressParser;
[myParser setShouldProcessNamespaces:NO];
[myParser setShouldReportNamespacePrefixes:NO];
[myParser setShouldResolveExternalEntities:NO];
NSURL *xmlURL = [NSURL fileURLWithPath:pathToFile];
myParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
[myParser setDelegate:self];
[myParser setShouldResolveExternalEntities:YES];
[myParser parse];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI: (NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ( [elementName isEqualToString:#"gx:coord"] ) {
polylineList = [[NSMutableArray alloc] init];
}
}
When the parser method runs and it finds the right elementName I want to retrieve the string data after the tag and add it to my NSMutableArray polylineList.
The other parameters in parser all return nil so am I missing something?
I managed to solve this myself using the method below
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if ((addRec) && (![string isEqualToString:#"\n"]))
{
NSArray *tmpArray = [[NSArray alloc] initWithObjects:string, nil];
if (polylineList.count > 0)
[polylineList addObject:string];
else
polylineList = [[NSMutableArray alloc] initWithArray:tmpArray];
}
}
I hope this is helpful to those who are using KML, MapKit or just parsing XML.
In ios i am using Xml soap parsing This is my response
<InsertResponse xmlns="http://OrderMe.solyn.in/"><InsertResult>[{"Result":"Success","AccessToken":"f60da1f1-40d7-483d-880a-82348dc20934","AppUserId":"35"}]</InsertResult></InsertResponse>
Then i am using This code for Get Response
-(void)parser:(NSXMLParser *) parser foundCharacters:(NSString *)string {
if (elementFound) {
// NSLog(#"%#",soapResults);
[soapResults appendString: string];
if ([Type isEqualToString:#"InsertResponse"] ) {
//--- Retrieving text of an element that is found---
NSLog(#"%#",string);
NSString *str = [[NSString alloc]initWithData:string encoding:NSUTF8StringEncoding];
NSArray *allData = [str JSONValue];
//NSString *loginID=[NSString stringWithFormat:#"%#",string];
//NSLog(#"Login ID Returned from web service is : %#",loginID);
}
}
}
in this code ** NSLog(#"%#",string);** this string is print
[{"Result":"Success","AccessToken":"f60da1f1-40d7-483d-880a-82348dc20934","AppUserId":"35"}]
so i dont know how to convert this string in array
I am wating response
please share your valuable knowledge
Regards,
Nishant Chandwani
Thanks .
You need to parse this string as JSON:
NSString *string = #"[{\"Result\":\"Success\",\"AccessToken\":\"f60da1f1-40d7-483d-880a-82348dc20934\",\"AppUserId\":\"35\"}]";
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
First this is xml parser.So how can we get the values from this.Let's come to below coding
In your .h part
//Step 1 : Add the Delegate classes
First of all you should add <NSXMLParserDelegate>
//Step 2 : Create necessary objects
NSXMLParser *parser;
NSMutableData *ReceviedData;
NSMutableString *currentStringValue;
NSMutableArray *arrayResult;
NSMutableArray *arrayAccessToken;
NSMutableArray *arrayAppUserId;
In your .m part
//Step 3 - Allocate your all Arrays in your viewDidLoad method
arrayAppUserId = [NSMutableArray alloc]init];
arrayResult = [NSMutableArray alloc]init];
arrayAccessToken = [NSMutableArray alloc]init];
//Step 4 - Create Connection in your viewDidLoad Like
[self createConnection:#"http://www.google.com"];//give your valid url.
-(void)createConnection:(NSString *)urlString
{
NSURL *url = [NSURL URLWithString:urlString];
//Step 5 - parser delegate methods are using NSURLConnectionDelegate class or not.
BOOL success;
if (!parser)
{
parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
parser.delegate = self;
parser.shouldResolveExternalEntities = YES;
success = [parser parse];
NSLog(#"Success : %c",success);
}
}
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSLog(#"Current Element Name : %#",elementName);
if ([elementName isEqualToString:#"Result"])
{
NSLog(#"The Result is==%#",elementName);
}
if ([elementName isEqualToString:#"AccessToken"])
{
NSLog(#"The AccessToken is==%#",elementName);
}
if ([elementName isEqualToString:#"AppUserId"])
{
NSLog(#"The appUserId is==%#",elementName);
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
currentStringValue = [[NSMutableString alloc] initWithString:string];
NSLog(#"Current String Value : %#",currentStringValue);
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:#"Result"])
{
[arrayResult addObject:currentStringValue];
}
if ([elementName isEqualToString:#"AccessToken"])
{
[arrayAccessToken addObject:currentStringValue];
}
if ([elementName isEqualToString:#"AppUserId"])
{
[arrayAppUserId addObject:currentStringValue];
}
currentStringValue = nil;
}
I am trying to grab a token from a website. Upon successful authentication, an XML document would be displayed.
I created a connection as shown below:
NSString *strURLQueryString = [NSString stringWithFormat:#"%#?username=%#&password=%#", kURL_LOGIN, nameString, passwordString];
NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:strURLQueryString]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
In order to display the output, I used this:
unsigned char byteBuffer[[receivedData length]];
[receivedData getBytes:byteBuffer];
NSLog(#"Output: %s", (char *)byteBuffer);
So some of the output of the returned document is as shown below:
<status>0</status><reason>User fetched.</reason><token>9cb7396dccabe68c067521db219afb83</token>
I have read many XML parsing implementation but I just could not implement it as it does not fulfil my need, and I just could not understand the complexity of its explanation.
Would appreciate if anyone could give me a good advice on how to go about.
- (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 ,, I hope this works....
The relevant NSXMLParserDelegate methods:
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName //etc
{ _inToken = [elementName isEqualToString:#"token"]; }
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName //etc
{ _inToken = NO; }
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if (_inToken) {
_token = string;
[parser abortParsing];
}
}
You should use XML parser.
It is easy to use, go all below steps to get best result:
Create XMLParser class subclasses from NSXMLParser, so you have a NSXMLParser.h and NSXMLParser.m class
your .h class must be like this:
#import <Foundation/Foundation.h>
#interface XMLParser : NSXMLParser <NSXMLParserDelegate>{
NSUInteger parsedCounter;
BOOL accumulatingParsedCharacterData;
BOOL didAbortParsing;
}
#property (nonatomic, strong) NSMutableString *currentParsedCharacterData;
#property (nonatomic, strong) NSMutableArray *currentParsedCharacterArray;
#end
And .m class :
#import "XMLParser.h"
#implementation XMLParser
#pragma mark Parser constants
// Limit the number of parsed data to 100.
static const NSUInteger kMaximumNumberOfFilesToParse = 100;
static NSUInteger const kSizeOfFileBatch = 10;
// Reduce potential parsing errors by using string constants declared in a single place.
static NSString * const kEntryElementName = #"dlResult";
static NSString * const kStringElementName = #"string";
#pragma mark NSXMLParser delegate methods
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
// NSLog(#"didStart");
// If the number of parsed earthquakes is greater than kMaximumNumberOfEarthquakesToParse, abort the parse.
if (parsedCounter >= kMaximumNumberOfFilesToParse) {
// Use the flag didAbortParsing to distinguish between this deliberate stop and other parser errors.
didAbortParsing = YES;
[self abortParsing];
}
if ([elementName isEqualToString:kEntryElementName]) {
_currentParsedCharacterArray = [[NSMutableArray alloc]init];
} else if ([elementName isEqualToString:kStringElementName]) {
accumulatingParsedCharacterData = YES;
_currentParsedCharacterData = [[NSMutableString alloc]init];
}
}
// return string between tags
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
// NSLog(#"foundCh");
if (accumulatingParsedCharacterData) {
// If the current element is one whose content we care about, append 'string'
// to the property that holds the content of the current element.
[_currentParsedCharacterData appendString:string];
NSLog(#"currentParsedCharacterData:%#",_currentParsedCharacterData);
}
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
// NSLog(#"didEnd");
if ([elementName isEqualToString:kStringElementName]) {
[_currentParsedCharacterArray addObject:_currentParsedCharacterData];
}
accumulatingParsedCharacterData = NO;
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
if (didAbortParsing == NO) {
// Pass the error to the main thread for handling.
[self performSelectorOnMainThread:#selector(handleError:) withObject:parseError waitUntilDone:NO];
}
}
#end
In .m class there are two const string:
static NSString * const kEntryElementName = #"dlResult";
static NSString * const kStringElementName = #"string";
those are string tags,the tags that you should implement are "status", "reason" "token"
from connection class, send data connection to XMLParser class like below:
#autoreleasepool {
// It's also possible to have NSXMLParser download the data, by passing it a URL, but this is not desirable
// because it gives less control over the network, particularly in responding to connection errors.
//
XMLParser *parser = [[XMLParser alloc] initWithData:data];
parser.currentParsedCharacterArray = [NSMutableArray array];
parser.currentParsedCharacterData = [NSMutableString string];
[parser setDelegate:parser];
[parser parse];
// depending on the total number of earthquakes parsed, the last batch might not have been a "full" batch, and thus
// not been part of the regular batch transfer. So, we check the count of the array and, if necessary, send it to the main thread.
if ([parser.currentParsedCharacterArray count] > 0) {
// send parsed data to another class or ...
// parser.currentParsedCharacterArray is parsed data
}
parser.currentParsedCharacterArray = nil;
parser.currentParsedCharacterData = nil;
}
if you have any question, ask me!
I got an iOS app. All data stores in xml files.
<?xml version="1.0" encoding="utf-8"?>
<objects>
<object
name="Скульптура Р. Исмагилова «Пермяк – соленые уши»"
xcoord="58.00998487478568"
ycoord="56.239829063415527"
type=""
description=""
external_name="gl1" />
</objects>
So, i want to parse this XML file to NSMutableArray
I do it with NSXMLParser deleagate class. This is class's code:
#implementation XMLParser
#synthesize aPLace;
- (XMLParser *) initXMLParser {
[super init];
appDelegate = (XMLAppDelegate *)[[UIApplication sharedApplication] delegate];
return self;
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict {
NSLog(#"parsing");
if([elementName isEqualToString:#"objects"]) {
//Initialize the array.
appDelegate.books = [[NSMutableArray alloc] init];
}
else if([elementName isEqualToString:#"object"]) {
//Initialize the book.
aPLace = [[Place alloc] init];
//Extract the attribute here.
aPLace.name = [[attributeDict objectForKey:#"name"] string];
NSLog(#"Reading name :%#", aPLace.name);
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if([elementName isEqualToString:#"objects"])
return;
if([elementName isEqualToString:#"object"]) {
[appDelegate.greenLine addObject:aPLace];
}
}
#end
You can see that there is NSLog(#"parsing"); in didStartElement function. But output is empty.
So, i implement parsing in AppDelegateClass's function applicationDidFinishLaunching
- (void)applicationDidFinishLaunching:(UIApplication *)application {
NSURL *url = [[NSURL alloc] initWithString:#"greenline_ru.xml"];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:url];
//Initialize the delegate.
XMLParser *parser = [[XMLParser alloc] initXMLParser];
//Set delegate
[xmlParser setDelegate:parser];
//Start parsing the XML file.
BOOL success = [xmlParser parse];
if(success)
NSLog(#"No Errors");
else
NSLog(#"Error Error Error!!!");
// Configure and show the window
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
}
and every time output is Error Error Error!!! why? What's the problem?
NSURL *url = [[NSURL alloc] initWithString:#"greenline_ru.xml"];
I think this is your problem. If you have file you should use something like
NSString *path = [[NSBundle mainBundle] pathForResource:#"greenline_ru"
ofType:#"xml"];
[[NSXMLParser alloc] initWithData:[NSData dataWithContentsOfFile:path]]
Use TBXML, this is quite easy to use...
Study this- http://www.tbxml.co.uk/TBXML/API.html
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 .