iphone : NSXMLParser fails to identify HTML special entity & - iphone

I simply cannot get NSXMLParser to recognize &
here is my XML:
<?xml version="1.1" encoding="UTF-8"?>
<root>
<myURL>http://www.mywebsite.com/info?id=32&page=5</myURL>>
</root>
Here is my parsing code:
-(void)getXml {
NSURL *xmlurl = [[NSURL alloc] initWithString:#"http://www.mywebsite.com/myxml.xml"];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlurl];
[xmlParser setDelegate:self];
[xmlParser parse];
[xmlParser release];
[dataurl release];
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
NSLog(#"Parser Error: %#", parseError);
}
- (void)parser:(NSXMLParser *)parser validationErrorOccurred:(NSError *)validError {
NSLog(#"Parser validation Error: %#", validError);
}
- (void)parserDidStartDocument:(NSXMLParser *)parser {
NSLog(#"Parser started");
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
NSLog(#"Found key: %#", elementName);
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
NSLog(#"Found Element: %#", string);
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
NSLog("done"):
}
Here is my output:
Found key: root
Found key: myURL
Found element: http://www.mywebsite.com/info?id=32
Found element: page=5
Found element:
Found key: myURL
The parser is not recognizing the & correctly and is splitting up my url.
I have seen many Stack questions on this issue but none of them have helped and I have read the Apple docs on NSXMLParser as well. Am I missing something here?
I am building with iOS 5.0 to an iPhone 4

Thank you, this is a great insight into the parser process but there were problems using it, maybe due to the features of Xcode 4.5.1
It turned out that assigning a NSString like #"" to a NSMutableString makes it immutable. Instead to set the starting value for the tempString I've had to use
self.tempString = [[NSMutableString alloc] initWithString: #""];
and the parser:foundCharacters method becomes
- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
[self.tempString appendString:string];
currentNodeContent = (NSMutableString*) [self.tempString stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
}
But that's one problem solved. Thanks.

According to the NSXMLParserDelegate documentation:
The parser object may send the delegate several
parser:foundCharacters: messages to report the characters of an
element. Because string may be only part of the total character
content for the current element, you should append it to the current
accumulation of characters until the element changes.
So the usual pattern of usage is to keep appending to a temporary string until the end of the element is reached:
.h
#property (nonatomic,retain) NSMutableString *tempString;
.m
#synthesize tempString;
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
self.tempString = #"";
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
[self.tempString appendString:string];
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
// do something with self.tempString
}

Related

WSDL/XML parsing iOS objective C

I would like some help to parse this Response. I think it is WSDL and would like to check "Successfully Entered" string. Below is the code:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sch="http://example.com/reg/abc">
<soapenv:Header/>
<soapenv:Body>
<sch:LoginResponse>
<sch:Status code=200>Successfully Entered</sch:Status>
<sch:Message>[CDATA[Successfully Entered]]</sch:Message>
</sch:LoginResponse>
</soapenv:Body>
</soapenv:Envelope>
EDIT: Below is the code I have implemented
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *)qName
attributes: (NSDictionary *)attributeDict
{
NSLog(#"START ELEMENT NAME ==> %#", elementName);
if( [elementName isEqualToString:#"sch:Status"])
{
if(!soapResults)
{
soapResults = [[NSMutableString alloc] init];
}
elementFound = YES;
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if( elementFound )
{
[soapResults appendString:string];
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
NSLog(#"END ELEMENT NAME ==> %#", elementName);
if( [elementName isEqualToString:#"sch:Status"])
{
NSLog(#"Found ==> %#", soapResults);
[soapResults setString:#""];
elementFound = FALSE;
}
}
Print log shows upto sch:LoginResponse and does not come to element name sch:Status
As per our chat, the problem is in the line:
<sch:Status code=200>Successfully Entered</sch:Status>
When code=200 is changed to code="200" it parses correctly.
In other words, the XML is formatted incorrectly. Attributes are supposed to have either a single (') or double quotation (") around the data. (See W3C XML recommendaiton)
Additionally, the delegate detects the error NSXMLParserAttributeNotStartedError in the XML when left unchanged:
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
NSLog(#"Error: %#", parseError.localizedDescription);
}
If the XML must be retrieved this way, prior to parsing you can use this to surround it with quotation marks to make it valid, however you'd need to do it for each possible code=###:
yourXMLString = [yourXMLString stringByReplacingOccurrencesOfString:#"code=200" withString:#"code=\"200\""];

How to parse the xml file have same tag name using nsxmlparser?

How do I parse this type of XML using NSXMLParser
<category> <categoryName> userName</categoryName> <categoryName>password</categoryName><category>
Declare array and a string in h file like:
NSMutableArray *aryCategory;
NSString *strCategroyName;
in .m file for starting Parser use:
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:yourData]; // your data will be instance of NSData or NSMutableData
parser.delegate = self;
[parser parse];
this will be done once you get your xml data. For handling result you can use NSXMLParserDelegate as follows:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
if ([elementName isEqualToString:#"category"]) {
aryCategory = [[NSMutableArray alloc] init];
strCategroyName = #"";
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
strCategroyName = [NSString stringWithFormat:#"%#%#", strCategroyName, string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:#"categoryName"]) {
[aryCategory addObject:strCategroyName];
strCategroyName = #"";
}
}
Now you will have your array fill with all of your category name.
Hope this helps :)
Write the <category> in didStart and didEnd elements which are the parser's delegates.

NSXML Parser in iphone

I need to get the value of the following xml , I am using NSXML parser for parsing this
<boolean xmlns="http://schemas.microsoft.com/2003/10/Serialization/">true</boolean>
I need to get the "true " value from the above xml .
What should I do inside the NSXML parser delegate methods?
#import "XMLParser.h"
#implementation XMLParser
- (NSString *)parseXMLFile: (NSURL *) url
{
outstring = [[NSMutableString alloc] init];
NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL: url];
[parser setDelegate: self];
[parser parse];
[parser release];
return [outstring autorelease];
}
//<boolean xmlns="http://schemas.microsoft.com/2003/10/Serialization/">true</boolean>
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
attributes:(NSDictionary *)attributeDict
{
if (qName) elementName = qName;
if (elementName) current = [NSString stringWithString:elementName];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
current = nil;
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (!current) return;
if ([current isEqualToString:#"boolean"])
[outstring appendFormat:#"%#\n", string];
}
// <boolean xmlns="http://schemas.microsoft.com/2003/10/Serialization/">true</boolean>
-(void) parserDidStartDocument:(NSXMLParser *)parser {
NSLog(#"parserDidStartDocument");
}
-(void) parserDidEndDocument: (NSXMLParser *)parser {
NSLog(#"parserDidEndDocument %#", outstring);
}
#end
For more detail regarding the nsxml parse Reference site here.
this may more help to you.
if you want true value then do following:
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
strVal=string;
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([elementName isEqualToString:#"boolean"])
{
//you can get 'true' value here
}
}

how to parse xml for ios development

So I know how to parse some XML structures but I am currently trying to parse this specific xml structure thats a bit different to what I am used to.
normally I would parse something like
<xml>
<data>
<name>Forrest</name>
<age>25</name>
<username>forrestgrant</username>
</data>
</xml>
But now I'm working with some xml like so..
<xml>
<data name="Forrest" age="25" username="forrestgrant" />
<other value="6" />
</xml>
how do I access those variables when they are structured like this?
This is how I would normally approach this task, which is baised of searching for the title tags and getting the data from each one.. however I am now trying to figure out how to parse this other style of xml.
- (void)startTheParsingProcess:(NSData *)parserData
{
[myDataArray release]; // clears array for next time it is used.
myDataArray = [[NSMutableArray alloc] init]; //initalizes the array
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:parserData]; //incoming parserDatapassed to NSXMLParser delegate which starts parsing process
[parser setDelegate:self];
[parser parse]; //Starts the event-driven parsing operation.
[parser release];
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if ([elementName isEqual:#"item"]) {
// NSLog(#"Found title!");
itemString = [[NSMutableString alloc] init];
}
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
[itemString appendString:string];
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if ([elementName isEqual:#"item"]) {
//NSLog(#"ended title: %#", itemString);
[myDataArray addObject:itemString]; //this is where i pass the values over to my array.
[itemString release];
itemString = nil;
}
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
// Passes myDataArray to the method that will sort and display the array into a uitableview.
[self startSortingTheArray:myDataArray];
}
any help would be greatly appreciated..
The xml data above provides the data as attributes on the xml element.
This callback method gives you access to the attributes as a dictionary of key values (attributeDict).
(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict
NSLog the dictionary out in that method to see the values:
NSLog(#"attributes: %#", attributeDict);
In your didStartItem: method, the attributes dictionary will contain values for all the XML attributes.

NSXMLParsing for particular tag value [duplicate]

I have an XML file that looks like this:
<country>
<routes>
<SourceCountry>Ireland</SourceCountry>
<SourcePort>Larne</SourcePort>
<DestinationCountry>UK</DestinationCountry>
<DestinationPort>Troon </DestinationPort>
</routes>
<routes>
<SourceCountry>Ireland</SourceCountry>
<SourcePort>Larne</SourcePort>
<DestinationCountry>UK</DestinationCountry>
<DestinationPort>Cairnryan </DestinationPort>
</routes>
<routes>
<SourceCountry>Ireland</SourceCountry>
<SourcePort>Belfast</SourcePort>
<DestinationCountry>UK</DestinationCountry>
<DestinationPort>Birkenhead </DestinationPort>
</routes>
<routes>
<SourceCountry>Ireland</SourceCountry>
<SourcePort>Belfast</SourcePort>
<DestinationCountry>Belgium</DestinationCountry>
<DestinationPort>Heysham </DestinationPort>
</routes>
<routes>
<SourceCountry>Belgium</SourceCountry>
<SourcePort>Warrenpoint</SourcePort>
<DestinationCountry>UK</DestinationCountry>
<DestinationPort>Heysham </DestinationPort>
</routes>
I want parse particular data for <SourceCountry> == Ireland and <DestinationCountry> == UK. How can I do this?
Use NSXMLParser
implement the delegate for this class ... <NSXMLParserDelegate>
implement the methods for this parser...
YOU will need the following methods..
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
You can read this tutorial; it is simple to use.
This may help
Accessing specific child elements when parsing RSS with NSXMLParser
You need to use XML parser, Use NSXMLParser to parse you data.
Below is the apple sample code of ImageMap in which they have used the NSXMLParser to parse XML content.
http://developer.apple.com/library/mac/#samplecode/ImageMap/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009015
Try this . . .
int element=0;
[self parseXMLFileAtURL:filepath];
following methods are the delegates of NSXMLParser
- (void)parseXMLFileAtURL:(NSString *)URL
{
NSURL *xmlURL = [NSURL fileURLWithPath:URL];
parser = [[ NSClassFromString(#"NSXMLParser") alloc] initWithContentsOfURL:xmlURL];
[parser setDelegate:self];
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
}
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
NSLog(#"found file and started parsing");
}
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if(([elementName compare:#"SourceCountry"])==NSOrderedSame)
element=1;
if(([elementName compare:#"SourcePort"])==NSOrderedSame)
element=2;
if(([elementName compare:#"DestinationCountry"])==NSOrderedSame)
element=3;
if(([elementName compare:#"DestinationPort"])==NSOrderedSame)
element=4;
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (element==1)
{
[TotalXMLArray addObject:string];
element=0;
}
if (element==2)
{
[TotalXMLArray addObject:string];
element=0;
}
if (element==3)
{
[TotalXMLArray addObject:string];
element=0;
}
if (element==4)
{
[TotalXMLArray addObject:string];
element=0;
}
}