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\""];
Related
XML file:
i can not parse the subfolder of XML shown below
i am able to parse the content of xml file by using method:
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
currentelement=[elementName copy];
if ( [elementName isEqualToString:#"Content"] ) {
item=[[NSMutableDictionary alloc]init];
}
}
but i cannot parse the sub folder "PictureURL", i am getting null if i parse this in
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if ([currentelement isEqualToString:#"PictureURL"])
{
[item setObject:string forKey:#"Info8"];
}
}
can any one let me know hoe to access the sub folder of the XML. thanks in advance
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.
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;
}
}
I am getting SOAP response and when parsing the response I am getting this: (As you can see from result which is currently stored as NSString is NSLoged itself contain xml format data)
<Menus>
<Table1>
<Restaurant_Name>CHICK-FIL-A</Restaurant_Name>
<Restaurant_id>2748</Restaurant_id>
<Phone>(404) 371-1466</Phone>
<billing_city>DECATUR</billing_city>
<billing_state>GA</billing_state>
<billing_zip_code>30030</billing_zip_code>
<billing_addr1>105 EAST TRINITY PLACE</billing_addr1>
</Table1>
</Menus>
The Code for the above generated response:
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict{
if([elementName isEqualToString:#"GetMenusByZipCodeResult"])
{
if(!soapResults)
{
soapResults = [[NSMutableString alloc] init];
}
recordResults = TRUE;
}
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if(recordResults)
{
[soapResults appendString:string];
}
//NSLog(#" soap: %#", soapResults);
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName
{
if([elementName isEqualToString:#"GetMenusByZipCodeResult"])
{
NSLog(#"soapResult FINAL : %#",soapResults);
recordResults = FALSE;
result.text = soapResults;
[soapResults release];
soapResults = nil;
}
}
The above mention data is result of soapResult.
How to read this data? I tried to reparse it but it is not helping.
Please help me.
If you want a simple XML to NSDictionary converter (including the text nodes), check out http://troybrant.net/blog/2010/09/simple-xml-to-nsdictionary-converter/
Use an XML parser like NSXMLParser
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSXMLParser_Class/Reference/Reference.html
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.